?
Solved

Memory allocation Problem

Posted on 2008-11-12
33
Medium Priority
?
274 Views
Last Modified: 2013-11-26
Hello,
I am having problems while allocating memory in the below part of code when i am debugging and checking the value for szlines it is not having any value it is showing 0 the same piece of code works fine in visual studio c++ 6.0 but it is giving problems in visual stdio .net 2005 .I replaced the code with new operator but it is giving run time error as source code not available .Thanks.

char      **szLines      = NULL;            // String
if (!nNumLines)
{
      szLines = (char**) malloc (sizeof (char*));
      szLines[0]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[0][0] = '\0';
}
0
Comment
Question by:Sohela
  • 14
  • 12
  • 4
  • +2
32 Comments
 
LVL 7

Expert Comment

by:Maverick_Cool
ID: 22947642
szLines[0][0] = 'a';
 szLines[0][1] = '\0';
check byy asigning some value... what do u get
0
 

Author Comment

by:Sohela
ID: 22947680
>>>>>>szLines[0][0] = 'a';
 szLines[0][1] = '\0';
its still same it is failing actually after this line
   szLines = (char**) malloc (sizeof (char*));
when i check in szlines it is showing as 00000 and the next statement it is failing
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22947898
you are trying to maintain an array of strings. so memory has to be allocated for 2 things

firstly - the total number of strings
secondly - for each string

char      **szLines      = NULL;            // String
if (!nNumLines)
{
      szLines = (char**) malloc (sizeof (char*));
      szLines[0]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[0][0] = '\0';
}

so

if char* szLines; //for a single string
szLines = new char[lenofstring];


for eg.
 
char** szLines;	
    int nNumLines;
 
    szLines = new char*[10];
	for (int i=0; i<10; i++)
	{
	 szLines[i] = new char[10];
	 strcpy(szLines[i],"TNT\n");
	}
	for (int i=0; i<10; i++)
		cout<<szLines[i];
 
-------------------------------------------------
so your code will have to be modified as follows:
char** szLines;
int nNumLines;
 
szLines = new char*[nNumLines];
	for (i=0; i<10; i++)
	szLines[i] = new char[strlen(szToken+1)];

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22947905
and my sample code works in VS 2005. Ofcourse you need to create a proper project
0
 

Author Comment

by:Sohela
ID: 22947929
actually nNumLines is zero i will get the number of lines later then what i am supposed to do and the loop
for (i=0; i<10; i++)
i didnt understand like is it mandatory we  repeat the loop 10times .Thanks a lot.
0
 

Author Comment

by:Sohela
ID: 22947961
When i tried to implement this code i am getting source code unavaialble while im debugging at this point
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948140
Can you post the entire code, please ?

When malloc returns 0, it means it didn't succeed allocating the requested amount of data. That might be because there's not enough memory available, or because there has been a memory corruption, or...
0
 

Author Comment

by:Sohela
ID: 22948169
char seps[]   = " &<>+!,;.()\\[]\"'|{}@#$%^*_=?~`:";

      char      **szLines      = NULL;            // String
      char      *pszLine      = NULL;
      int            nNumLines      = 0;            // Number of lines
      
      char separat[] = "\0";
      separat[0] = '\n';
      char ch = 13;
      separat[1] = ch;

            // Get the string token
      char *szToken = NULL;
      szToken = strtok(pszLineStr, separat);
      int nSize = 10;
      
      while (szToken)
      {
            // Allocate memory
            if (!nNumLines)
            {
                  szLines = new char*[nSize];
                  for (int i=0; i<10; i++)
                  szLines[i] = new char[strlen(szToken+1)];

                  /*szLines = (char**) malloc ((nSize) * sizeof (char*));
                  szLines[0]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
                  szLines[0][0] = '\0';*/
            }
            else
            {
                  szLines  = (char**)realloc (szLines, (nNumLines + 1) * sizeof (char*));
                  szLines[nNumLines]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
                  szLines[nNumLines][0] = '\0';
            }

            //if (nNumLines >= 1)
            //      szToken[strlen (szToken) - 1] = '\0';
            strcpy (szLines[nNumLines++], szToken);

            szToken = strtok (NULL, separat);
      
      }
0
 

Author Comment

by:Sohela
ID: 22948175
before this im allocating memory to a char** and double pointer also once while debugging it showed out of memory error what am i supposed to do .Thanks
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 2000 total points
ID: 22948243
>>       char separat[] = "\0";
>>       separat[0] = '\n';
>>       char ch = 13;
>>       separat[1] = ch;

separat is now no longer null terminated. It is an array of size 2 that contains two characters : '\n' and '\r'.

This is a very odd way of initializing a string. Why not just :

        char separat[] = "\n\r";

?


>>       szToken = strtok(pszLineStr, separat);

I assume that pszLineStr is a correctly null-terminated string ?


>>                   szLines[i] = new char[strlen(szToken+1)];

I'm sure you meant :

                  szLines[i] = new char[strlen(szToken) + 1];

Otherwise, you allocate a memory block that is two characters too short.



>>                   szLines  = (char**)realloc (szLines, (nNumLines + 1) * sizeof (char*));
>>                   szLines[nNumLines]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));

It is a VERY bad idea to mix C-style memory allocation (malloc etc.) with C++ style memory allocation (new etc.). You use both in your code, and that will mess things up at some point.
0
 

Author Comment

by:Sohela
ID: 22948262
{
      szLines = (char**) malloc ((nSize) * sizeof (char*));
      szLines[0]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[0][0] = '\0';
}
else
{
      szLines  = (char**)realloc (szLines, (nNumLines + 1) * sizeof (char*));
      szLines[nNumLines]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[nNumLines][0] = '\0';
}

no actually i was using this code previously i just wanted to check if there was problem with malloc so i used new instesd but its the same my code is failing at
      szLines = (char**) malloc ((nSize) * sizeof (char*));  szLines is showing 00000 and if i try to use new operator  it is showing error source code not available

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948357
>> no actually i was using this code previously

Well, it would be more useful if you posted the original code that caused your problem. Could you do that ?


How about the other issues I pointed out ?


If you run the code outside of the debugger, do you have the same problem ? (just add an if statement to check the szLines value after the malloc call).
0
 

Author Comment

by:Sohela
ID: 22948371
well this the original code which is giving me problem

char seps[]   = " &<>+!,;.()\\[]\"'|{}@#$%^*_=?~`:";
char      **szLines      = NULL;            // String
char      *pszLine      = NULL;
int      nNumLines      = 0;            // Number of lines
      
   char separat[] = "\0";
   separat[0] = '\n';
   char ch = 13;
   separat[1] = ch;

   // Get the string token
   char *szToken = NULL;
   szToken = strtok(pszLineStr, separat);
    int nSize = 10;

    while (szToken)
    {
       // Allocate memory
       if (!nNumLines)
       {
      szLines = (char**) malloc ((nSize) * sizeof (char*));
      szLines[0]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[0][0] = '\0';
      }
     else
     {
      szLines  = (char**)realloc (szLines, (nNumLines + 1) * sizeof (char*));
      szLines[nNumLines]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[nNumLines][0] = '\0';
    }

ya i have the same problem if im not debugging

0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22948389
first of all usage of malloc is not recommended in C++ programs.


>>>actually nNumLines is zero i will get the number of lines later then what i am supposed to do and the loop
for (i=0; i<10; i++)
i didnt understand like is it mandatory we  repeat the loop 10times .Thanks a lot.
-------------------------------------------------------------------------------------------------------

it is not mandatory to repeat the loop 10 times. that was just an example. You can replace it with a max value which you feel may be the number of lines.

>>>When i tried to implement this code i am getting source code unavaialble while im debugging at this point

source code not available is not a problem.
I suggest you first use my logic and implement your program and see the output by introducing some logging statements. Use iostream outputs or open a log file and dump the output to this file.
If you need to debug then you need to point to the correct source code with which you have generated the executable. This is the only reason why you get the source code not available error.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948400
The first two issues I pointed out are still there in this code.


There is one more :

>>       szLines = (char**) malloc ((nSize) * sizeof (char*));

Why do you allocate space for 10 char*'s if in the next iteration, you're realloc'ing it to 2 ?


>> ya i have the same problem if im not debugging

Then you're likely dealing with a memory corruption caused by code that was run earlier. You'll have to find out whether and where such a corruption occurs (buffer overflows are likely candidates for example) and fix it.
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22948410
the very first time since nNumLines is 0 the realloc code will always execute and this is usually not recommended. You should ideally not do a  realloc without having first done a malloc.

Please change your logic and I suggest you remove the usage of C memory management functions in your C++ code.
0
 

Author Comment

by:Sohela
ID: 22948433
What function can i use instead of realloc
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948530
>> the very first time since nNumLines is 0 the realloc code will always execute

The realloc code will execute when nNumLines is NOT 0.


>> and I suggest you remove the usage of C memory management functions in your C++ code.

But this is not the cause of Sohela's problem.
0
 

Author Comment

by:Sohela
ID: 22948561
well i changed my code as unfinity suggested and used new operator but it is giving source code unavailable even though it is debugging the correct cpp

int nSize = 10;
      
      while (szToken)
      {
            // Allocate memory
            if (!nNumLines)
            {
                  szLines = new char*[nSize];
                  //for (int i=0; i<10; i++)
                  szLines[0] = new char[strlen(szToken)+1];
                  szLines[0][0] = '\0';

i changed even this as you suggested    char separat[] = "\n\r";
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948602
How about this ?

>> >>       szToken = strtok(pszLineStr, separat);
>> 
>> I assume that pszLineStr is a correctly null-terminated string ?

and this ?

>> >>       szLines = (char**) malloc ((nSize) * sizeof (char*));
>> 
>> Why do you allocate space for 10 char*'s if in the next iteration, you're realloc'ing it to 2 ?


And more importantly, did you look into this :

>> >> ya i have the same problem if im not debugging
>> 
>> Then you're likely dealing with a memory corruption caused by code that was run earlier. You'll have to find out whether and where such a corruption occurs (buffer overflows are likely candidates for example) and fix it.
0
 

Author Comment

by:Sohela
ID: 22948631
>>>>>>
and this ?
>> >>       szLines = (char**) malloc ((nSize) * sizeof (char*));

no no i was just giving and testing if i give maybe more it may work itis actually like this

                    szLines = (char**) malloc (sizeof (char*));
      szLines[0]  = (char*)malloc ((strlen (szToken) + 1) * sizeof (char));
      szLines[0][0] = '\0';

>>>>>    szToken = strtok(pszLineStr, separat);

ya pszLineStr is a correctly null-terminated string


0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948668
>> itis actually like this

Euhm. You keep saying that the "actual code" is different from what you posted. How do you expect us to help you if you don't give us accurate information ?

In any case, I'd start looking into the memory corruption possibility.
0
 

Author Comment

by:Sohela
ID: 22948705
I am sorry i thought i have posted the right code but it was my fault i am extremely sorry for tha it is showing the same error source could unavailabe and it pops a dialog to click ok or disassembly when i click on disassembly and continue debugging it is giving out of memory pop up.Thanks
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22948853
Don't worry about that - that's just the standard library source that are apparently not available.

You should look into the real problem - ie. the reason that malloc returns 0. And for that you need to check whether there is sufficient memory (how much memory does your application use at the moment of the problem ?) and if so, check for memory corruptions.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22952702
>>>> You should look into the real problem

I fully agree but have doubts whether the posted code should be corrected at all. It is neither C nor C++ and most of the statements are unnecessary or wrong or both ... Note, I don't want to blame you, but you really should consider to start completely from the beginning as any attempt to repair the above code would arise new problems.

If you want to see a real C++ solution of your problem, check the last comment of the following link

 http:Q_23896994.html  
 
A  C++ solution using strtok and char arrays (based on some of your code above) is below (I didn't compile it, so it may have typos).

Note, you can call the getTokenArr in a nested loop while you can't do that with strtok. The strtok uses an internal buffer for the string passed with the first call.
if you would call the strtok for a second parsing of each line while the first parsing was not finished, the previous buffer was thrown away and any following call would fail.

>>>> char separat[] = "\n\r";

FYI: You never will find a '\r' = CR = carriage-return = ASCII:13 = HEX: 0D in a textfile opened in textmode. When reading a textfile Windows removes the CR from input stream. When opening the file in binary mode, you'll have a pair of  carriage-return + linefeed (ASCII: 13 10, HEX: 0D 0A, C: "\r\n").



...
 
const int NEW_TOKENS = 8;
 
char** addToken(char* szToken, char** szTokens, int& nToken, int& nAlloc)
{
   char** szNewTokens = NULL;
   
   if (nAlloc < 0 || nAlloc < nToken)
   {
       nAlloc   = nToken = 0;
       szTokens = NULL;
   }
   if (nToken >= nAlloc)
   {
      szNewTokens = new char*[nAlloc + NEW_TOKENS];
      memcpy(szNewTokens, szTokens, nAlloc*sizeof(char*));
      memset(&szNewTokens[nAlloc], 0, NEW_TOKENS * sizeof(char*));
      if (nAlloc > 0)
      {
         delete []szTokens;
      }
      nAlloc  += NEW_TOKENS;
      szTokens = szNewTokens;
   }
   szTokens[nToken] = new char[strlen(szToken)+1];
   strcpy(szTokens[nToken]), szToken);
   ++nToken;
   return szTokens;
}
 
 
char** getTokenArr(char* pszStr, char separat[], int& nTokens)
{
   char** szTokens   = NULL;         // Array of tokens
   int    nSize     = 0;            // Number of allocated elements
      
 
   // Get the string token
   char*  szToken = NULL;
   szToken = strtok(pszStr, separat);
   
   while (szToken != NULL)
   { 
      szLines = addToken(szToken, szTokens, nTokens, nSize); 
      // don't change the nTokens and nSize 
      // they were managed by the addToken above
 
      // here call strtok again ...
      
      ...
  }
  return szTokens;
}
 
Note the calling function has to delete the array returned
 
     char separat[] = "\r\n";
     int nTokens = 0;
     char** szTokens = getTokenArr(pszStr, separat, nTokens);
     ...
 
     // if the szTokens wasn't needed anymore delete it
     delete []szTokens;
     szTokens = NULL;

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22957780
May I ask why you gave a B grade ? That usually means that something was missing in the answer and/or that something is still unclear. If that's the case, then please do not hesitate to ask for clarification where needed.
0
 

Author Comment

by:Sohela
ID: 22957926
actually when i changed andt ested the code it was executed once but the second time again it is giving the same error
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22958006
So, your problem is not resolved ? If you want, you can get the question re-opened.
0
 

Author Comment

by:Sohela
ID: 22958090
And  one more thing what memory problem i am getting in my system i have done the same code on another system but i am not getting the problem whereas in my system i am getting both systems are of same configuration and have same memory size
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22958115
That doesn't matter - memory corruption is a strange beast, and can have bad results on one system while it doesn't on another. It all depends on the exact circumstances.

I suggest you re-open this question so we can continue helping you.
0
 

Author Comment

by:Sohela
ID: 22958161
Im sorry but how am i supposed to reopen the question
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22958172
You can use the "Request Attention" link for that.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

749 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