我搞砸了要学习的函数中的C指针。我创建了一个字符串数组,并希望在函数中foo
使用指向指针的指针对其进行更改。然后我将其打印出来,仅供参考。
问题是:如果我“正常”创建它:char array[] = "yeah"
,该代码将无法正常工作,并且在控制台上会看到一堆奇怪的字符。但是,如果我使用创建它malloc
,它就可以工作。我真的很想了解区别。
这有效:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void foo(char **ptr);
int main(int argc, char *argv[]) {
char *array = malloc(sizeof("yeah")); //I need to malloc here, or it doesn't work. Why ?
strcpy(array, "yeah");
printf("array before : %s \n", array);
char *ptr = array;
char **pt = &ptr;
foo(&array);
printf("array after : %s \n", array);
free(array);
}
void foo(char **ptr) {
char *truc = malloc(sizeof(char) * 20); //I need to malloc here, else it doesn't work. Why ?
strcpy(truc, "then");
*ptr = truc;
}
但这不是,它将在控制台上显示讨厌的字符:
void foo(char **ptr);
int main(int argc, char *argv[]) {
char array[] = "yeah"; //created "normally"
printf("array before : %s \n", array);
char *ptr = array;
char **pt = &ptr;
foo(&array);
printf("array after : %s \n", array);
free(array);
}
void foo(char **ptr) {
char truc = "then";
*ptr = truc;
}
之间有什么区别?
char array[] = "yeah";
和
char *array = malloc(sizeof("yeah");
strcpy(array, "yeah");
您应该注意的第一件事:代码:char array[] = "yeah";
将起作用。
注意:如果执行此操作,则不会调用free(array)
它,因为它不是指向动态分配的内存的指针,并且不需要动态返回到堆中。它存在于堆栈中。继续阅读...
但是foo()
这里的功能是问题。当foo()
调用时,字符串truc
(也可以声明为char truc[] = "then";
)存在于堆栈帧中,该堆栈帧是程序存储器的一部分,仅在foo()
返回之前存在。如果更改array
为指向该堆栈框架内的内存,则该函数返回时会发生什么?该堆栈帧变为未定义状态,您只能指向垃圾内存。
如果要更改中的字符串内容array
,可以确保缓冲区足够长,并且foo()
可以strcpy(array, "then")
放入其中。因此,您无需更改指针本身,而只需更改其指向的内存即可。这不是我所谓的好的软件设计,但是为了举例,它对您有用。像这样:
void foo(char * ptr)
{
strcpy(ptr, "then");
}
malloc()
in不能正常工作main()
呢?如果您不在 malloc()
中main()
,则array
表示表示一个数组。标识符本身不是指针,而是数组。但是,它会衰减为一个指针,或者,如果您愿意,它的行为就像一个指针。这就是为什么您可以将它作为一个整体传递的原因,就像您将其传递给一样foo()
。现在,如果您引用的地址 array
,如&array
,(char*)array
,&array
,&array[0]
都是一样的-指针的开始array
。在这种情况下,您foo()
实际上是在向的内存写入内存地址array
。
这是做什么的?好吧,技术答案是不确定的行为。但是我猜想它正在将32位整数(一个内存地址)写入到一块内存中,该内存曾经代表一个字符串中的4个8位字符。所以现在您已经损坏了四个字符。并且,如果按照您的显示foo()
使用malloc()
,也会引起内存泄漏。
整洁的部分是您的字符串正好是四个字符,因此这不会破坏'\0'
字符串末尾的空终止符。我猜,您看到的恰好是四个垃圾字符?
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句