c - 解除引用问题

时间:2010-04-29 11:16:15

标签: c dereference

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

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

程序打印出第一行,然后我得到段错误。

我的计划如下:

#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的指针来实现阵列。

我不明白为什么我应该在第二轮得到一个段错误,我会感激任何建议。

非常感谢

3 个答案:

答案 0 :(得分:4)

尝试:

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

当前版本相当于

*(*(memory_ref + i));

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

之后读取内存

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

编辑:第一次迭代的原因是:

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

答案 1 :(得分:2)

这看起来像是一个优先问题。首先评估[],然后评估*秒。您需要的是第一个代码示例的以下内容...

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

答案 2 :(得分:1)

快速解决方法是使用

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

但我怀疑你的行有问题

 memory[0] = "Mem 0";

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

您需要使用strncpy

明确复制数据

e.g。     char s =“Mem 0”;     strncpy(memory 1,s,max(strlen(s)+ 1,29))// max = 30 =(29 char +'\ 0',因为那是你分配的行长度 - 更好的#define这是一个常数