0

Say I have the code:

char* word  = malloc (sizeof(char) * 6);
strcpy(word, "hello\0extra");
puts(word);
free(word);

This compiles just find and Valgrind has no issue, but is there actually a problem? It seems like I am writing into memory that I don't own.

Also, a separate issue, but when I do overfill my buffer with something like

char* word  = malloc (sizeof(char) * 6);
strcpy(word, "1234567\0");
puts(word);
free(word);

It prints out 1234567 and Valgrind does catch the problem. What are the consequences of doing something like this? It seems to work every time. Please correct me if this is wrong, but from what I understand, it is possible for another program to take the memory past the 6 and write into it. If that happened, will printing the word just go on forever until it encounter a nul character? That character has just been really confusing for me in learning C strings.

Foundry
  • 33
  • 7
  • Oh the only real problem is you'll get a nasty case of NASAL DEAMONS. – IdeaHat Dec 10 '14 at 18:51
  • `strcpy(word, "hello\0extra");` will stop after the 6th char (terminator) so there is no problem with this contrived example. – Weather Vane Dec 10 '14 at 18:54
  • Your second question, `strcpy` will copy whatever you tell it into overflow space as long as it doesn't cause a segment fault. Whether or not that breaks something, depends on what it has overwritten. Just assume it will break something. – Weather Vane Dec 10 '14 at 18:59

4 Answers4

2

The first strcpy is okay

strcpy(word, "hello\0extra");

You create a char array constant and pass the pointer to strcpy. All characters (including the first \0) is copied, the remainder is ignored.

But wait... You have some extra characters. This makes your const data section a bit larger. Could be a problem in embedded environment where flash space is rare. But there is no run-time problem.

harper
  • 13,345
  • 8
  • 56
  • 105
0
strcpy(word, "hello\0extra");

This is valid because the second paramter should be a well formed string and it is because you have a \0 as your 6th character which forms a string of length 5.

strcpy(word, "1234567\0");

Here you are accessing memory which you don't own/allocated so this is an access violation and might cause crash.(seg fault)

Gopi
  • 19,784
  • 4
  • 24
  • 36
0

With your first call to strcpy, NUL is inserted into the middle of the string. That means that functions that deal with null-terminated strings will think of your string as stopping with the first NUL, and the rest of your string is ignored. However, free will free all of it and valgrind will not report a problem because malloc will store the length of the buffer in the allocation table and free will use that entry to determine how many bytes to free. In other words, malloc and free are not meant to deal with null-terminated strings, so the NUL in the middle of the string will not affect them. Instead, free determines the length of the string based on how many bytes you allocated in the first place.

With the second example, you overflow the end of the buffer that was allocated by malloc. The results of that are undefined. In theory, that memory that you are writing to could have been allocated by another call to malloc, but in your example, nothing is done with the memory after your buffer, so it is harmless. The string-processing functions think of your string as ending with the first NUL, not with the end of the buffer allocated by malloc, so all of the string is printed out.

Arthur Laks
  • 524
  • 4
  • 8
  • Maybe it's just me, but this doesn't seem especially clear. `malloc` and `free` don't care what's in memory; `free` will free the six bytes malloced. `strcpy` only writes `hello\0` into `word`, so `extra` will only exist in the string table of the program--it never gets copied anywhere. – yellowantphil Dec 10 '14 at 19:20
0

Your first question has a couple good answers already. About your second question, on the consequences of writing one byte past the end of your malloced memory:

It's doubtful that mallocing 6 bytes and writing 7 into it will cause a crash. malloc likes to align memory on certain boundaries, so it's not likely to give you six bytes right at the end of a page, such that there would be an access violation at byte 7. But if you malloc 65536 bytes and try to write past the end of that, your program might crash. Writing to invalid memory works a lot of the time, which makes debugging tricky, because you get random crashes only in certain situations.

yellowantphil
  • 1,483
  • 5
  • 21
  • 30