为什么 strlen 不适用于分配的内存?

Why does strlen not work on mallocated memory?

我写了下面的代码:

[all the required initialization]

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

L = (char*) malloc((mid)*sizeof(char));

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

[data treatment and free()]

然后 printf 我得到了这个结果:

longueur de mid: 2
longueur de L: 3

为什么输出不同?

strlen 迭代直到找到空字节。 malloc 使分配的 space 未初始化,因此空字节可能会随机出现。毕竟,由于访问未初始化的内存,这是未定义的行为。

单独确定 malloc 块的大小是不可能的。将大小存储在单独的变量中,例如 LsizeRsize.


备注:

  • don't cast the result of malloc
  • 乘以 sizeof(char) 是多余的,因为 sizeof(char) == 1
  • malloc
  • 之后使用free
  • size_t、a.k.a 对应的格式说明符。 "return type of strlen and the sizeof operator" 是 %zu%d 用于 ints1

1 正如@chux 在此答案的评论中指出的那样

正如有人部分提到的那样,strlen() 将输入的输入转换为正确的内存位置,然后该位置递增 1,直到找到空字符。尝试在 malloc() 调用的指针上使用 strlen() 的问题在于,返回的指针返回的数据可以是任何数据,具体取决于 OS 处理内存的方式。

如果您希望您的指针在分配内存时引用一组有保证的空字符,您可以使用此代码:

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

那么至少当你使用 strlen() 时,你会得到一个零。

如果你必须使用malloc(),那么你可以使用这个代码:

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

在这两段代码中,我假设 L 和 R 被声明为 char*

并且一定要在使用 calloc 和 malloc 分配的所有内存上使用 free(),否则您可能会遇到内存泄漏,这可能会导致您重新启动计算机。

如果想快速的将固定字节数放入内存,在分配内存后使用:

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

但将 x 更改为零以外的任何值,否则它将为空。

这是一个示例程序,它的功能更符合您的预期:

#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; 
}

即使启用了编译器选项 -Wall-Wextra,上面的代码在我的编译器中编译得很好,没有警告。