Why does strlen not work on mallocated memory?

こ雲淡風輕ζ 提交于 2019-12-30 07:50:53

问题


I wrote the following code:

[all the required initialization]

printf("longueur de mid: %d\n",mid);
printf("longueur de n-mid: %d\n",n - mid);

L = (char*) malloc((mid)*sizeof(char)); 
R = (char*) malloc((n - mid)*sizeof(char)); 

printf("longueur de L: %d\n",strlen(L));
printf("longueur de R: %d\n",strlen(R));

[data treatment and free()]

And with the printf I got this result:

longueur de mid: 2
longueur de n-mid: 2
longueur de L: 3
longueur de R: 3

Why do the outputs differ?


回答1:


strlen iterates until a null byte is found. malloc leaves the allocated space uninitialized, so a null byte may occur randomly. After all, it's undefined behavior due to the access of uninitialized memory.

Determining the size of a mallocated block alone is not possible. Store the size in seperate variables like Lsize and Rsize.


Notes:

  • don't cast the result of malloc
  • multiplying by sizeof(char) is redundant as sizeof(char) == 1
  • use free after malloc
  • the corresponding format specifier for size_t, a.k.a. "return type of strlen and the sizeof operator" is %zu; %d is used on ints1

1 as @chux noted in the comments to this answer




回答2:


As someone partially mentioned, strlen() converts the input fed to it into the correct memory location then that location is incremented by 1 until the null character is found. The problem with trying to use strlen() on a pointer from a malloc() call is that the data returned at the returned pointer can be anything depending on how your OS handles memory.

If you want your pointers to reference a guaranteed set of null characters when allocating memory, you can use this code:

L = calloc(1,mid+1); 
R = calloc(1,n - mid+1); 

Then at least when you use strlen(), you'll get a zero.

If you must use malloc(), then you can use this code:

L = malloc(1,mid+1); 
R = malloc(1,n - mid+1); 
memset(L,0,mid);
memset(R,0,n - mid);

In both pieces of code, I assumed L and R are declared as char*.

and definitely use free() on all memory allocated with calloc and malloc or you can expect a memory leak which could lead into you restarting your computer.

If you want to put in a fixed number of bytes in memory in a quick way, use this after allocating memory:

memset(L,x,mid);
memset(R,x,n - mid);

but change x to any value other than zero or it will be null.

Here's a sample program that does more like what you expect:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(){
  int size=10;
  char* a=calloc(1,100); // allocate 100 null's and store pointer to them at 'a'
  printf("%d \n",size); // print wanted size
  printf("%d \n",strlen(a)); // print length of memory space which = 0
  memset(a,'A',size); // put 10 A's at the beginning of allocated memory
  printf("%d \n",strlen(a)); // print length again which now = 10
  printf("%s \n",a); // print memory (which is 10 A's)
  free(a); // free the memory
  return 0; 
}

The above compiled fine in my compiler with no warnings even with the compiler options -Wall and -Wextra enabled.



来源:https://stackoverflow.com/questions/33399074/why-does-strlen-not-work-on-mallocated-memory

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!