“正常”创建数组与使用malloc之间的区别

阿多普利

我搞砸了要学习的函数中的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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

bash数组使用@ vs *,两者之间的区别

malloc和calloc之间的区别?

属性和使用ALTER创建的列之间的区别?

创建新数组和清除长度之间的区别

创建新类与使用export const之间的区别

Array.CreateInstance与使用new运算符创建新的数组实例之间的区别

使用numpy追加或数组追加之间的区别-Python

两种创建数组的方式之间的区别

在postgres中创建另一个表和使用数组之间有什么区别

使用malloc和calloc创建2D数组

使用ARRAY []和'{}':: int []创建数组之间在性能上有区别吗?

使用malloc和不使用malloc创建结构的区别

数组和向量之间的区别

使用IEnumerator和使用数组作为属性之间的区别

malloc(sizeof(ptr))和malloc(sizeof(ptr *))之间的区别?

使用括号和方括号在C ++中创建动态数组之间的区别

无法理解使用malloc创建2D数组

使用PHP的两个数组之间的区别

使用malloc创建动态结构数组

在C语言中,普通数组和使用malloc创建的数组有什么区别?

创建字符数组的方法之间的区别

如何使用malloc在NASM程序集中创建新的char数组

使用Malloc()使用指针创建整数数组

对齐的malloc和标准malloc之间的区别?

memset()和使用for循环的initializinng数组元素之间的区别?

数组和集合之间的区别

“使用”和“正常”数据库连接之间的区别

使用数组和指针偏移表示法之间的实际区别

使用 malloc 创建和传递数组作为函数