【问题标题】:c - dereferencing issuec - 取消引用问题
【发布时间】:2010-04-29 11:16:15
【问题描述】:

我已经简化了一个我一直试图隔离问题的问题,但它没有帮助。

我有一个二维字符数组来表示内存。我想将对内存模拟的引用传递给函数。在测试内存内容的函数中,我只想遍历内存并打印出每一行的内容。

程序打印出第一行,然后出现段错误。

我的程序如下:

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

void test_memory(char*** memory_ref)  {

    int i;
    for(i = 0; i < 3; i++)  {
        printf("%s\n", *memory_ref[i]);
    }
}

int main()  {
    char** memory;
    int i;
    memory = calloc(sizeof(char*), 20);
    for(i = 0; i < 20; i++)  {
        memory[i] = calloc(sizeof(char), 33);
    }

    memory[0] = "Mem 0";
    memory[1] = "Mem 1";
    memory[2] = "Mem 2";

    printf("memory[1] = %s\n", memory[1]);

    test_memory(&memory);

    return 0;
}

这给了我输出:

memory[1] = Mem 1
Mem 0
Segmentation fault

如果我更改程序并通过取消引用 memory_ref 在函数中创建内存的本地版本,那么我会得到正确的输出:

所以:

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

void test_memory(char*** memory_ref)  {

    char** memory = *memory_ref;
    int i;
    for(i = 0; i < 3; i++)  {
        printf("%s\n", memory[i]);
    }
}

int main()  {
    char** memory;
    int i;
    memory = calloc(sizeof(char*), 20);
    for(i = 0; i < 20; i++)  {
        memory[i] = calloc(sizeof(char), 33);
    }

    memory[0] = "Mem 0";
    memory[1] = "Mem 1";
    memory[2] = "Mem 2";

    printf("memory[1] = %s\n", memory[1]);

    test_memory(&memory);

    return 0;
}

给我以下输出:

memory[1] = Mem 1
Mem 0
Mem 1
Mem 2

这是我想要的,但是制作内存的本地版本是没有用的,因为我需要能够从函数中更改原始内存的值,而这只能通过取消引用指向原始 2d char 的指针来实现数组。

我不明白为什么我会在第二轮中出现 seg 错误,如果您有任何建议,我将不胜感激。

非常感谢

【问题讨论】:

    标签: c dereference


    【解决方案1】:

    试试:

    printf("%s\n", (*memory_ref)[i]);
    

    当前版本相当于

    *(*(memory_ref + i));
    

    这是因为[] 运算符的优先级高于取消引用*。这意味着当i 大于0 时,您会尝试在char*** 临时memory_ref 之后读取内存

    第二个版本等于(*memory_ref)[i],这意味着您将索引正确的内存。

    编辑:它在第一次迭代中起作用的原因是:

    *(*(memory_ref + 0)) == *((*memory_ref) + 0)
    

    【讨论】:

    • 这行得通。非常感谢。我不确定为什么。我猜想括号允许在尝试访问取消引用操作的结果之前完成取消引用操作。不过,这仍然不能解释数组打印中第一个字符串的行为。为什么我第一次没有遇到段错误?非常感谢乔
    • @Joe 至于为什么它在第一轮有效,请参阅我编辑的答案。
    【解决方案2】:

    这看起来像是一个优先级问题。 [] 首先被评估,* 第二。对于您的第一个代码示例,您需要类似以下内容...

    printf("%s\n", (*memory_ref)[i]);
    

    【讨论】:

      【解决方案3】:

      快速解决方法是使用

      printf("%s\n", (*memory_ref)[i]);
      

      但我怀疑你的台词有问题

       memory[0] = "Mem 0";
      

      这些不会将字符串“Mem 0”复制到您的内存阵列中。它们使 memory[i] 指向字符串。

      您需要使用strncpy 显式复制数据

      例如 字符 s = "内存 0"; strncpy( memory1, s, max( strlen(s) + 1, 29) ) // max of 30= (29 char + '\0' 因为这是你分配的行长度 - 最好#define this as一个常数

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-09
        • 1970-01-01
        • 2013-07-04
        • 1970-01-01
        • 1970-01-01
        • 2011-03-31
        • 2012-10-30
        • 2011-10-11
        相关资源
        最近更新 更多