OS: Linux
CC: GCC 4.8.2
Targer: Change size of char* -> to smaller
PROBLEM: Size after change is same...
line is string with data...
Code fragment:
char * tmp = NULL;
[...]
tmp = malloc(sizeof(char) * 8);
strncpy(tmp, line, sizeof(char) * 8);
[...]
Now smaller tmp:
printfTest(tmp); //Content dump
nevAddr = realloc(tmp, sizeof(char) * 3);
if(newAddr != NULL)
{
tmp = newAddr;
}
else
{
free(tmp);
puts("Realloc - FAIL");
exit(VALID);
}
printfTest(tmp); //Content dump
printfTest function:
void printfTest(char * data)
{
printf("Test: '%s'", tmp);
}
Result:
Test: 'BLABLABL' //8chars
Test: 'BLABLABL' //8chars (!? Why)
Where is my fail?
You are confusing two different concepts of "size". Here's a character array with 100 chars:
char x[100]; // sizeof(x) / sizeof(x[0]) == 100
strcpy(x, "short string");
The size of the x
array is still 100, even though the length of the string, strlen(x)
is just 12.
(Actually, maybe you could benefit from a basic introduction to strings in C, like this tutorial instead of reading this answer. )
When you print a string in C, the software keeps printing characters until it finds a \0
(the null character), even if this involves reading pass the end of the array. In fact, the compiler cannot know if it has gone past the array. It just blindly continues until the finds the null character.
The strcpy
above actually writes 13 bytes, not 12. It prints the 12 characters and the null character on the end.
This means that an array in C that is intended to hold a string must actually have one extra space to hold the null character. If you want to store "world"
, you must have at least six characters
char y[5];
strcpy(y,"hello"); // undefined behaviour, as y is too small
char z[6];
strcpy(z,"hello"); // OK
(And no, strncpy
does not fix this problem. "No null-character is implicitly appended at the end of destination if source is longer than num. ")
Anyway, to return to your question. One way to shorten the string would be to write a null character in the appropriate place:
char x[100];
strcpy(x, "hello");
printf("%s\n", x); // prints "hello"
x[3] = '\0'; // replace the second 'l' with the null
printf("%s\n", x); // prints "hel"
To change the string, you need to change the bytes, perhaps with code like mine, or perhaps with another strcpy
.
Simply calling realloc
does not actually change any of the bytes in the string, it merely frees some of the memory nearby.