【问题标题】:adding pointers to dynamic pointer array in a loop in c在c中的循环中添加指向动态指针数组的指针
【发布时间】:2012-10-02 19:01:40
【问题描述】:

我有一个表示表格中一行的结构:

typedef struct {
    char *a;
    char *b;
} row;

我有一个函数可以根据 db 数据初始化该行并返回指向它的指针

row* get_row(dbrow d) {
    row *r = malloc(sizeof(row));
    r->a = malloc(5);
    strcpy(r->a, d.a);
    r->b = malloc(5);
    strcpy(r->b, d.b);
    return r;
}

最后,我有一个以row **rows 为参数的函数:

void get_rows(row **rows) {
    ...
    rows = malloc(rowNumber * sizeof(row*));
    int i;
    for (i = 0; i < rowNumber; i++) {
        rows[i] = get_row(dbrow);
    }
}

get_row 按预期工作并返回一个指向有效行结构的指针,但 gdb 显示 rows[0] (以及所有其他)永远不会获得新值,也就是说,它总是指向同一个地址,几乎就像rows[i] = get_row(dbrow) 行不存在。

【问题讨论】:

  • rowNumber 来自哪里?你能把你的整个代码贴出来吗?
  • rowNumber 被初始化为 1。周围的代码处理数据库访问,有点乱,它可以工作,而且确实对显示的代码有影响。指针分配之前的所有内容都可以正常工作。

标签: c pointers struct malloc


【解决方案1】:

...gdb 表明 rows[0](以及所有其他)永远不会获得新值...

我在这里假设您查看的是 get_rows 函数的返回值,而不是其局部变量 rows 的值。问题来了:

rows = malloc(rowNumber * sizeof(row*));

您正在为函数接收到的原始指针的副本分配一个新值,而不是原始指针。此更改将在函数之外不可见。

如果您需要为参数分配一个新值,那么您将需要添加另一个间接级别。记住; C 中的一切都是按值传递的。因此,您的函数应该以 row*** 作为其参数:

void get_rows(row ***rows) {
    if(!rows) {
        signal_some_error();
        return;
    }
    ...
    *rows = malloc(rowNumber * sizeof(row*));
    ...
}

此外,正如 user1700513 所指出的,您正在为一行分配一个row*。这不可能是您的实际代码,因为它会导致编译器错误。

【讨论】:

  • 问题在 get_rows 返回之前就出现了,就在赋值行之后。如果仅在范围内,它应该仍然有效,对吧?
  • 所以,我上面提到的还是一个需要修复的错误,否则你的功能是没用的。如果函数内部也存在问题,那么您还没有发布所有相关的代码。 get_row 每次都会返回一个 mallocd 指针,所以除非你在某个地方踩到内存,否则你的问题会丢失一些东西。 malloc 不可能连续两次返回相同的地址而不在其间删除。 d.ad.b 是否正确终止了 C 字符串? 5 字节是否足以容纳它们?在将rows 传递给函数之前,您如何声明它?
  • @cbaby: ...rowNumber 的值是多少?这里缺少信息,我们需要更多代码。
  • 找到它:get_rows 需要获取对行 **rows 的引用,正如您所指出的,我正在“按值”传递指针。
  • @cbaby: ... :D。很高兴你解决了。只是为了迂腐;在 C 中没有引用传递之类的东西。一切都是按值传递的,因此当您需要为参数分配新值时,您必须添加额外的间接级别。
【解决方案2】:

row r = malloc(sizeof(row)); 更改为row* r = malloc(sizeof(row));。我想知道为什么你没有收到编译器警告。

【讨论】:

  • 这应该是一个错误,因为没有从void*row 的隐式转换。我敢打赌这是一个错字,真正的代码声明了一个指针。
  • @cbaby:最好逐字复制代码。你试过我的建议了吗?
猜你喜欢
  • 1970-01-01
  • 2015-03-29
  • 2017-02-07
  • 1970-01-01
  • 2012-07-16
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多