【问题标题】:Modified struct in some functions changes pointer and causes free() to fail某些函数中修改的结构会更改指针并导致 free() 失败
【发布时间】:2015-10-12 03:20:38
【问题描述】:

请原谅我在一行上运行多个语句,但这是我不明白的。我有三个名为 function1、function2 和 function3 的函数,每个函数分别调用 makeblock、makeblock2 和 makeblock3。请参阅下面的代码。我试图让它们都在屏幕上产生相同的结果。 makeblock函数运行正常,调用function1后的结果是:

1 A
2 B

function2 和 function3 在尝试释放内存指针时无法正常工作并产生分段错误。我怀疑这与指针在 makeblock2 和 makeblock3 函数中的处理方式有关。

所以基本上,我正在寻找一种快捷方式,使数据可访问,而无需将修改后的地址值返回给调用者。短于 block* dat=*datain;block** data=&dat; 的东西会是理想的,前提是它可以工作,但我在 makeblock2 和 makeblock3 中的尝试都失败了。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct{int a;char b;} block;

void printdata(block* data){
    while(data->a != 0){printf("%d %c\n",data->a,data->b);data++;}
}

void makeblock3(block** datain){
    block** data=&(*datain);
    (**data).a=1;(**data).b='A';(*data)++;
    (**data).a=2;(**data).b='B';(*data)++;
}

void makeblock2(block** datain){
    block** data=datain;
    (**data).a=1;(**data).b='A';(*data)++;
    (**data).a=2;(**data).b='B';(*data)++;
}

void makeblock(block** datain){
    block* dat=*datain;block** data=&dat;
    (**data).a=1;(**data).b='A';(*data)++;
    (**data).a=2;(**data).b='B';(*data)++;
}

void function1(){block* data=calloc(1,100000);makeblock(&data);printdata(data);free(data);}
void function3(){block* data=calloc(1,100000);makeblock3(&data);printdata(data);free(data);}
void function2(){block* data=calloc(1,100000);makeblock2(&data);printdata(data);free(data);}

int main(){function3();return 0;}

【问题讨论】:

  • 正如我在您的其他问题中所问的,您为什么要通过引用传递参数?
  • 这两个问题不相关。我问这个是因为我想学习新的东西。我通过引用传递,因为我想在函数内的结构中修改我想要的任何值,但仍然能够从函数外部使用相同的指针,这就是调用 function1 时发生的情况,但我正在尝试做一个更简洁的版本。
  • 您不需要通过引用传递 指向结构的指针。您可以从指针修改结构。我的第一个函数可以正常工作。

标签: c function pointers struct memory-address


【解决方案1】:

简单的解决方案:不要通过引用传递

void makeblock(block* data){
    data->a=1; data->b='A'; data++;
    data->a=2; data->b='B'; data++;
}

如果你真的想通过引用传递但不希望被引用的对象发生变化(这与通过引用传递的通常原因相反),那么复制被引用的对象:

void makeblock(block** data_p){
    block* data = *data_p;
    data->a=1; data->b='A'; data++;
    data->a=2; data->b='B'; data++;
}

【讨论】:

  • 我认为外部结构必须始终通过引用传递,函数才能修改它们。外部数值变量类型似乎就是这种方式。也许手册过于复杂了。
  • @Mike:如果你有一个指向对象的指针,你可以通过指针修改那个对象。所以如果你想修改一个int,你需要传递一个指向int的指针。现在,您可以将结构直接传递给函数(在这种情况下,函数会获得一个副本),但由于制作副本的成本,通常不鼓励这样做。所以你经常传递一个指向结构的指针。但是您实际上并没有尝试传递结构。您试图通过引用传递一个结构数组。因为数组衰减为指针,所以效果与将指针传递给第一个元素是一样的。
猜你喜欢
  • 2016-01-21
  • 2016-11-10
  • 2015-10-26
  • 1970-01-01
  • 2020-11-20
  • 2013-11-27
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多