为什么 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
块的大小是不可能的。将大小存储在单独的变量中,例如 Lsize
和 Rsize
.
备注:
- 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
用于 int
s1
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
,上面的代码在我的编译器中编译得很好,没有警告。
我写了下面的代码:
[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
块的大小是不可能的。将大小存储在单独的变量中,例如 Lsize
和 Rsize
.
备注:
- don't cast the result of
malloc
- 乘以
sizeof(char)
是多余的,因为sizeof(char) == 1
- 在
malloc
之后使用 size_t
、a.k.a 对应的格式说明符。 "return type ofstrlen
and thesizeof
operator" 是%zu
;%d
用于int
s1
free
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
,上面的代码在我的编译器中编译得很好,没有警告。