We help IT Professionals succeed at work.

Deleting pointer arrays

rkbhumagani
rkbhumagani asked
on
306 Views
Last Modified: 2010-04-01
Getting errors when I execute this code,
I believe there is something wrong with the way I am deleting the tokenList
Can someone please check this out for me please.

Thanks,
Raj

CODE:


#include <stdio.h>
#include <string.h>

int tokenize(char *m_buffer, char* m_seperators, char** m_tokenList, int m_tokenCount)
{
      char *token;
      int count=0;      
      
      token = strtok (m_buffer,m_seperators);      
      
      while (token!=NULL && (count<m_tokenCount))
      {
            printf("%d", count);

            m_tokenList[count] = new char[strlen(token)];
            sprintf(m_tokenList[count],"%s",token);            
            
            count++;
            
            token = strtok( NULL, m_seperators );
      }            
      
      return 0;
}

int main(int argc, char* args[])
{
      char *tokenList[8] = {NULL};
      char *newBuffer = new char[25];

      strcpy(newBuffer,"ONE=TWO=THREE=FOUR=FIVE=SIX");

      tokenize(newBuffer,"=\n",tokenList,8);

      for(int i=0;i<8;i++)
      {
            if(tokenList[i]!=NULL)
            {
                  printf("\ni=%d",i);
                  printf("\ntokenList[%d]=%s",i,tokenList[i]);                  
            }
            else
            {
                  printf("\ntokenList[%d] is NULL",i);
            }
      }

      for (i=0;i<8;i++)
      {
            delete [] tokenList[i];
      }

      return 0;
}
Comment
Watch Question

AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
Hi rkbhumagani,
> int tokenize(char *m_buffer, char* m_seperators, char** m_tokenList,
> int m_tokenCount)

Your function type is passing by value the pointer to an array, so it can not change the calling function's variable.
Try passing a reference to it.

David Maisonave (Axter)
Cheers!
AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
Here's the corrected code:
#include <stdio.h>
#include <string.h>

int tokenize(char *m_buffer, char* m_seperators, char** &m_tokenList, int m_tokenCount)
{
    char *token;
    int count=0;    

    token = strtok (m_buffer,m_seperators);    

    while (token!=NULL && (count<m_tokenCount))
    {
        printf("%d", count);

        m_tokenList[count] = new char[strlen(token) +1];
        sprintf(m_tokenList[count],"%s",token);          

        count++;

        token = strtok( NULL, m_seperators );
    }          

    return 0;
}

int main(int argc, char* args[])
{
    char **tokenList = new char*[8]();
    char *newBuffer = new char[25];

    strcpy(newBuffer,"ONE=TWO=THREE=FOUR=FIVE=SIX");

    tokenize(newBuffer,"=\n",tokenList,8);

    for(int i=0;i<8;i++)
    {
        if(tokenList[i]!=NULL)
        {
            printf("\ni=%d",i);
            printf("\ntokenList[%d]=%s",i,tokenList[i]);              
        }
        else
        {
            printf("\ntokenList[%d] is NULL",i);
        }
    }

    for (i=0;i<8;i++)
    {
        delete [] tokenList[i];
    }
    delete [] tokenList;

    return 0;
}

AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
Axter,
> m_tokenList[count] = new char[strlen(token) +1];

Notice that I added a +1.  The original code was not including the NULL terminator in require length.


David Maisonave (Axter)

Author

Commented:
I am able to print the data, that is not my problem, the issue is deleting tokenList:

This is the output I get:

012345
i=0
tokenList[0]=ONE
i=1
tokenList[1]=TWO
i=2
tokenList[2]=THREE
i=3
tokenList[3]=FOUR
i=4
tokenList[4]=FIVE
i=5
tokenList[5]=SIX
tokenList[6] is NULL
tokenList[7] is NULL

and then I get a dialog box with the following message

Debug Error!
Program: C:\ENG\Codebase\test2\Debug\test2.exe
DAMAGE: after Normal block [#52] at 0x002F0FE0
(Press Retry to debug the application)

If I remove this part:

  for (i=0;i<8;i++)
     {
          delete [] tokenList[i];
     }


it runs fine, so it looks like I am not de-allocating memory properly.
The pointers in the tokenList array point to parts of newBuffer. Delete newBuffer only.
i.e.

--------8<--------
int main(int argc, char* args[])
{
    char **tokenList = new char*[8]();
    char *newBuffer = new char[25];

  // ...

    delete [] tokenList;
    delete [] newBuffer;


    return 0;
}
--------8<--------

strtok works by poking '\0' characters into the buffer, which you are tokenising. It doesn't do any memory allocation.
AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
>>I am able to print the data, that is not my problem, the issue is deleting tokenList:

It doesn't matter if you're able to print the data.
Writing to areas that are not allocated properly will cause undefined behavior, which include runtime errors when de-allocating memory.

Please try the code changes, before dismissing it.

You're getting the error because you're not allocating enough memory.
AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
>>it runs fine, so it looks like I am not de-allocating memory properly.

The problem is that you're not allocating memory properly.

Removing deallocation is just resulting in a memory leak, which you're not going to get a runtime error for in your program.
AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
To reiterate:
The following line of code is the reason you're getting a runtime error:

m_tokenList[count] = new char[strlen(token)];

You can fix the above code by just adding one:

m_tokenList[count] = new char[strlen(token) +1];


Please try the code change, so you can verify.
> To reiterate:

David is right. I didn't read it properly.

Author

Commented:
I used the exact code you have sent and I get the following error message:


The instruction at "0x00401f53" referenced memory at "0xcdcdcdcd". The memory could not be "read"

Click on OK to terminate the program
Click on CANCEL to debug the program

Senior Software Engineer
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
I also recommend you post the new code, even if you think it's the same code.

Author

Commented:
Hello Axter,

it works now, i made the following change
m_tokenList[count] = new char[strlen(token) +1];
and it works fine. Thanks a lot man. Was juggling between 2 - 3 different thigns and failed to see your point.

I assummed that to delete an array of pointers:

char *tokenList[8];

I needed to do something different other than

for (int i=0;i<8;i++)
{
   delete [] tokenList[i];
}

So this is a valid way to delete the pointer array, or is there any other better way. In short is this programming method better or do you suggest any improvements.

Thanks,
Raj
AxterSenior Software Engineer
CERTIFIED EXPERT

Commented:
>>So this is a valid way to delete the pointer array, or is there any other better way. In short is this programming method better or do you suggest any improvements.

I always recommend avoiding using new and delete when you can.
You can avoid using new and delete, by using std::vector<std::string>, which will give you an array of strings.

By using a vector, you don't have to worry about calling new or delete, or managing the size or allocations/deallocations.

Author

Commented:
Thank you Axter. I was intentionally avoiding STL to check out with regular data types. But I think I will get back to using vectors. Thanks a lot.

Raj
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.