C 为什么strlen不能处理位置错误的内存?

C 为什么strlen不能处理位置错误的内存?,c,malloc,strlen,C,Malloc,Strlen,我编写了以下代码: [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

我编写了以下代码:

[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()]
通过
printf
我得到了这个结果:

longueur de mid: 2
longueur de n-mid: 2
longueur de L: 3
longueur de R: 3
为什么输出不同?

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

无法单独确定
malloc
ated块的大小。将大小存储在单独的变量中,如
Lsize
Rsize


注:

  • sizeof(char)
    相乘是多余的,因为
    sizeof(char)==1
  • malloc
  • size\u t
    的相应格式说明符,即“strlen
    的返回类型”和
    sizeof
    运算符”是
    %zu
    <代码>%d用于
    int
    s1


1正如@chux在对该答案的评论中指出的,正如有人部分提到的,strlen()将输入转换为正确的内存位置,然后该位置递增1,直到找到空字符。尝试在malloc()调用的指针上使用strlen()的问题在于,返回指针处返回的数据可以是任何内容,具体取决于操作系统处理内存的方式

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

L = calloc(1,mid+1); 
R = calloc(1,n - mid+1); 
L = malloc(1,mid+1); 
R = malloc(1,n - mid+1); 
memset(L,0,mid);
memset(R,0,n - mid);
那么,至少当您使用strlen()时,您会得到一个零

如果必须使用malloc(),则可以使用以下代码:

L = calloc(1,mid+1); 
R = calloc(1,n - mid+1); 
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更改为零以外的任何值,否则它将为null

下面是一个示例程序,其功能与您期望的更为相似:

#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; 
}
#包括
#包括
#包括
int main(){
int size=10;
char*a=calloc(1100);//分配100个null并将指向它们的指针存储在“a”
printf(“%d\n”,大小);//需要打印的大小
printf(“%d\n”,strlen(a));//打印内存空间的长度,其中=0
memset(a,'a',size);//在分配内存的开头放10个a
printf(“%d\n”,strlen(a));//再次打印长度,现在为10
printf(“%s\n”,a);//打印内存(10 a)
释放(a);//释放内存
返回0;
}

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

您想了解C-“strings”到底是什么,因为C中没有数据类型“string”。如果您使用
空字符进行初始化
(零),您将看到差异。i、 e.
L=calloc(mid,sizeof(char))
R=calloc((n-mid),sizeof(char))
(注意:要存储字符串
mid
,必须分配
mid+1
,以便为空终止字符提供空间)您已分配内存,但未将任何内容放入内存。因此,它的内容是随机的,并且可能有任何字符串长度。
sizeof(char)
是没有意义的,但是
sizeof(L)
不是,因为即使
L
的类型更改为其他类型,例如
wchar\t
,它也会正常工作。类型名称几乎不应该传递给
sizeof
。一个好答案的建议注释:
printf(“longueur de L:%d\n”,strlen(L))是UB-应该是
%zu
strlen()
返回一个
size\u t
,与类型
malloc(size\u t n)
相同。感谢您的澄清。我不认为问题是由非初始化引起的。即使我使用这些数据,这个问题也会发生。例如,当我保留2*sizeof(char)时,字符串中总是有第三个字符。或者,正确的做法是用NULL初始化它。@White-Uhm,是的,问题是由于访问未初始化的内存造成的,正如我和其他答案的创建者所提到的。这是未定义的行为。随机性(从C标准的角度)。