tags:

views:

76

answers:

3

I do something like that in the loop :

char* test = "\0";

test = strcat(test, somestr);
...
char* tmp = strstr(test, 0, len);

free(test);
test = tmp;

And get memory leak. What I do wrong?

+1  A: 

There are a couple of problems:

  1. strcat will append a string to the destination buffer. You need the first parameter to be a buffer not a string literal pointer. Here is an example of a char buffer or also called an array of chars: char test[1024];

  2. The return value of strcat is a pointer to the destination buffer, it is not a newly allocated string on the heap. So you shouldn't call free on the return value.

Brian R. Bondy
+1  A: 

You can't strcat to test because you are initially pointing it to a constant char *. You need to assign memory for it. strcat won't do it.

Change your code to something like:

char* test = (char*)malloc(20*sizeof(char));
test[0] = '\0'; // nothing on this string to begin with
strcat(test, "something");
free(test);

Also, this won't work:

char* tmp = strcat(test, 0, len);

Since there is no strcat function with three parameters.

Remember. 99.9% of the time there will be a free call for each malloc allocation.

Pablo Santa Cruz
Then I have one more question. How can I remove last k elements from buffer?
Nikita
In C strings, you don't "remove" last elements - you move the '\0' end marker to terminate the string at the new position.
Arkadiy
How can I do it ? By the way I acctually have a string in unicode format. Does it mean that I need to calculate not the length of the string but the last usefull byte and put '\0' after it?
Nikita
+2  A: 

You don't actually have a memory leak (in the code you posted anyway), but you do several things wrong.

char* test = "\0";

This declares pointer named test and initializes it to point to some literal array of two bytes { 0, 0 }

test = strcat(test, somestr);

This tries to append something to the end of that string literal (and since as a C string it is empty it would be like a string copy). Literal values often are stored in memory that is not writable, so copying something into this memory would likely cause an error (segmentation fault or SIGSEGV on many operating systems). Additionally you only have two bytes of storage pointed to by test, which means that unless somestr refers to a string whose strlen is greater than 1 you would end up attempting to write over some other memory (whatever happens to be after the "\0" that test points to).

char* tmp = strstr(test, 0, len);

I don't know what is going on here since strstr only takes 2 arguments (both of them const char *).

free(test);

Here you are attempting to free non-heap allocated memory. The heap is where malloc, realloc, and calloc get the memory they allocate. Calling free with a memory location that was not returned by one of these functions (and a few other functions on some systems) is an error because free does not know what to do with them.

You should probably keep in mind that often memory is huge array of bytes, and that the pointers you use are like array indexes. The system you are using may be able to distinguish between some areas of this array and determine how you can access them (readable, writable, and/or executable). But it is still just an array of bytes. When you have a string (such as "foo") that means that somewhere in RAM there are four bytes ( 3 letters + the \0 terminator byte) and you can access this area by knowing its index within the array of bytes that is RAM. There are likely other things that are stored adjacent to your string (such as { ..., 4, 2, 'f', 'o', 'o', 0, 99, 3, 2, ...}) so you have to try to make sure you stay within the space of that memory without wandering into the adjacent data.

nategoose