3

Let's say I have something like this:

char *array,*mat;
array= (char*)malloc(BUFFER * sizeof(char));
fscanf("%s",array);
mat = (char*)malloc(strlen(array) * sizeof(char));
strcpy(mat1, strarr1);

So basically, I'm storing some text and then copying it over, but what happens if the original text is smaller than the BUFFER size? Does my original array occupy the size I allocated for it or does it only occupy the size of the string it contains?

Henrique
  • 45
  • 4
  • Please post some proper code not a hotch potch or typos. `fscanf("%s",array);` does not compile. – Weather Vane May 26 '17 at 14:55
  • `malloc(strlen(array) * sizeof(char))` probably needs to be one byte longer (for nul terminator) but it is unclear what you are trying to do. – Weather Vane May 26 '17 at 14:57
  • Any new string, that is null terminated, becomes the new data. The old data remains, but nothing beyond the `NULL` terminator is considered by string functions. If it is required that the entire buffer be clear, use memset() – ryyker May 26 '17 at 15:34

3 Answers3

4

The original array doesn't change its size. It occupies the exact size you allocated for it.

The data your store in a memory location simply overwrites the bytes that were previously written in that location.

If you allocated more space than you're using (for your string), those extra bytes aren't touched and they keep the same data they had before.

If you allocated less space than you're using, then you have an overflow.

jweyrich
  • 31,198
  • 5
  • 66
  • 97
2

The array array will have the same size, no matter how long the string is. The size is determined at the malloc statement and does not change afterwards. The array mat will be as long as the string.

Remember to allocate one extra charecter, for null.

And when coding c (not c++), do not cast malloc. Here is why: Do I cast the result of malloc?

klutt
  • 30,332
  • 17
  • 55
  • 95
2

When you allocate memory to an address, that memory persists, and is re-usable, until you free it.
For example:

char *buf1 = malloc(15);
strcpy(buf1, "15 characters."); //exactly 15 characters including NULL
|1|5| |c|h|a|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|...
^ beginning    and             ^ end of allocated memory

If you allocate memory to another buffer with more memory than the first, and initialize it with the same content:

char *buf2 = malloc(20);
strcpy(buf2, "15 characters."); //exactly 15 characters including NULL
strcpy(buf1, buf2); //strcpy is successful, resulting memory is populated with:
|1|5| |c|h|a|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|

But, if buf2 was created with much less content than buf1, the remaining content of buf1 would remain, but would not be considered by any of the string functions as they look for the NULL terminator to determine end of string. For example:

char *buf2 = "short"; // contains 6 characters including NULL
strcpy(buf1, bu2); //strcpy is successful, and memory includes remnants old content
|s|h|o|r|t|\0|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|
           ^^ end of new string, the rest is just artifact

Caution: some of the string functions ( such as strncpy ) will not always append a NULL character:

No null-character is implicitly appended at the end of destination if source is longer than num.

To mitigate this, enough room must always be included for the NULL character if you need the resultant char array to be considered a C string, and in the case described above, you must explicitly append a NULL char to the end of the buffer. i.e., for strncpy():

strncpy (target, source, n);
target[n] = 0;

Another useful function when working with allocated memory is memset. It is a good practice when re-using the same buffer over several operations, to reset all positions in memory to NULL:

memset(buf1, 0, 15);//results in...
|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
ryyker
  • 22,849
  • 3
  • 43
  • 87