提问人:tekkyprograms 提问时间:7/26/2023 最后编辑:Vlad from Moscowtekkyprograms 更新时间:7/26/2023 访问量:83
C程序调用malloc导致总线错误?
C program calling malloc results in bus error?
问:
我编写了这段代码来声明一个指针,然后为 int 类型动态分配 4 个字节的内存,然后在其中存储一些数据。 应指向保存 int 类型数据的地址。然后,程序应使用 .我还包含了从堆中释放已分配内存的函数。我不明白为什么我会收到总线错误。相同的代码已由对等节点执行,并且运行良好。我正在使用 Mac M2 并在 上运行代码。可能导致此错误的原因是什么?p
p
6
dereferencing operator
free()
vscode
#include <stdio.h>
#include <stdlib.h>
void foo(int *a){
a = (int*)malloc(sizeof(int));
}
int main(){
int *p;
foo(p);
*p = 6;
printf("%d",*p);
free(p);
return(0);
}
错误消息如下:zsh: bus error
请注意,如果我要删除该函数并替换调用行,那么程序可以正常工作。为什么在前面的方法中使用它会导致总线错误?foo()
p = (int*)malloc(sizeof(int));
答:
在函数中,参数是一个局部变量。您正在将结果分配给该函数,但这对此函数调用之外的程序没有影响。foo
a
malloc
就目前而言,您正在取消引用未初始化的指针,从而导致未定义的行为。如果成功,您还会发生(在本例中为短暂的)内存泄漏,因为以后无法释放此内存。malloc
为此,您需要将指针传递给指针。
void foo(int **a) {
*a = malloc(sizeof(int));
}
int main(void) {
int *p;
foo(&p);
*p = 6;
printf("%d", *p);
free(p);
return 0;
}
您可能还想养成检查成功的习惯。malloc
由于要更改指针的值,因此需要传递指针的地址。否则,您只需获得地址的副本即可。
#include <stdio.h>
#include <stdlib.h>
void foo(int **a){
*a = malloc(sizeof(int));
}
int main(){
int *p;
foo(&p);
*p = 6;
printf("%d",*p); // 6
free(p);
return(0);
}
在 C 语言中,参数按值传递给函数。这意味着相对于您的程序,该函数处理 中声明的指针值的副本。foo
p
main
因此,函数中副本的任何更改都会使原始指针保持不变。
您可以按以下方式想象该函数及其调用
foo(p);
//...
void foo( /*int *a */ ){
int *a = p;
a = (int*)malloc(sizeof(int));
}
正如你所看到的,它是在函数中声明的局部变量,它被更改了。原始指针保持不变。函数参数是函数的局部变量。a
p
因此,当指针保持不变且未初始化时,例如取消引用指针p
*p = 6;
导致总线错误。
若要更改函数中的对象(包括指针),需要通过引用传递它。
在 C 语言中,通过引用传递意味着通过指向对象的指针间接传递对象。因此,取消引用传递的指针,您可以直接访问指针指向的对象,并可以更改它。
因此,您的程序应如下所示
#include <stdio.h>
#include <stdlib.h>
void foo( int **a )
{
*a = malloc(sizeof(int));
}
int main( void )
{
int *p;
foo( &p );
if ( p != NULL )
{
*p = 6;
printf( "%d\n", *p );
}
free(p);
return 0;
}
注意两个方面。
第一种是将不带参数的函数声明为main
int main( void )
第二个是在 C 中(与 C++ 相反),您不需要转换从函数返回的指针。也就是说,你可以写malloc
*a = malloc(sizeof(int));
此外,在取消引用之前,您应该检查函数中更改的指针是否不是空指针。另一方面,可以为 null 指针调用该函数。p
main
free
评论