Solved

Deleting pointer arrays

Posted on 2006-06-12
16
238 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;
}
0
Comment
Question by:rkbhumagani
  • 9
  • 4
  • 3
16 Comments
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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!
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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;
}

0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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)
0
 

Author Comment

by:rkbhumagani
Comment Utility
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.
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
The pointers in the tokenList array point to parts of newBuffer. Delete newBuffer only.
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
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.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>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.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>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.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 30

Expert Comment

by:Axter
Comment Utility
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.
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
> To reiterate:

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

Author Comment

by:rkbhumagani
Comment Utility
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

0
 
LVL 30

Accepted Solution

by:
Axter earned 500 total points
Comment Utility
>>I used the exact code you have sent and I get the following error message:

Try using your original code, and just change the line of code for the allocation.
m_tokenList[count] = new char[strlen(token) +1];

0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
I also recommend you post the new code, even if you think it's the same code.
0
 

Author Comment

by:rkbhumagani
Comment Utility
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
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>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.

0
 

Author Comment

by:rkbhumagani
Comment Utility
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
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now