你能解释一下下面的内存是如何分配来容纳这么大的字符串的吗,即使我给出的malloc
大小只有一个字节
char **str;
int len = 1;
str = malloc(sizeof(char*)*len);//wont this allocate only one byte in heap?
str[0] = "This is a string";//this is more than one byte
printf("%s",str[0]);
我对它的工作原理感到非常困惑。
您没有分配一个字节。
表达式sizeof(char*)*len
可以简化为sizeof (char *)
,即字符指针的大小。这通常是 4 或 8。
然后你只需在那里存储一个指针,字符串文字"This is a string"
的值是该文字出现在内存中的地址,所以这样:
str[0] = "This is a string";
只需对str[0]
(这是一个指针)执行单个指针大小的分配,不会复制任何字符。正好一个指针是您分配了多少空间,因此一切都很好。
你没有分配你认为你正在分配的东西。
当你说
char **str;
这不是一个可以容纳一个字符串的变量。 这是一个可以容纳多个字符串数组的变量。
当你说
int len = 1;
str = malloc(sizeof(char*) * len);
您正在设置str
以容纳一根字符串。 也就是说,在这种情况下,len
计算字符串的数量,而不是字符串的长度。
然后当你说
str[0] = "This is a string";
您正在用指向字符串常量的指针填充str
的一个字符串。 编译器为您分配了字符串常量内存,因此您不必这样做。 在这种情况下,您所做的只是复制指针。 您不会复制整个字符串,因此不必为其分配更多内存。 这类似于你刚才说
char *p;
p = "This is a string";
如果要为整个字符串分配内存,并实际复制整个字符串,它可能如下所示:
const char *string_to_copy = "This is a string";
str[0] = malloc(strlen(string_to_copy) + 1); /* +1 for */
if(str[0] == NULL) exit(1);
strcpy(str[0], string_to_copy);
如果你想使用 str
来保存多个字符串,它可能看起来像这样:
len = 4;
str = malloc(sizeof(char*) * len);
if(str == NULL) exit(1);
str[0] = "This";
str[1] = "is";
str[2] = "a";
str[3] = "test.";