2010-04-29 64 views
2

我已简化了一直试图隔离问题的问题,但它不起作用。c - 取消引用问题

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

该程序打印出第一行,然后我得到seg故障。

我的程序如下:

#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数组的指针来完成。

我不明白为什么我会在第二轮遇到赛格错误,我会很感激任何建议。

非常感谢

回答

4

尝试:

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

当前版本相当于

*(*(memory_ref + i)); 

这是因为[]操作符比提领*更高的优先级。这意味着当i大于0您尝试读取内存后char***临时memory_ref

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

编辑:它适用于第一次迭代的原因是:

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

这工作。非常感谢。我不知道为什么,但。 我猜想,括号允许提领操作试图访问提领操作的结果之前完成。 这仍然没有按”牛逼是解释在阵列打印的第一个字符串的行为。我为什么没有得到赛格故障第一次圆的? 非常感谢 乔 – Joe 2010-04-29 11:24:44

+0

看到我的编辑答案,'[]'比'*更高的优先级'。 – 2010-04-29 11:26:17

+0

@Joe至于为什么它第一次工作,请参阅我编辑的答案。 – 2010-04-29 11:28:23

2

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

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

快速的解决办法是使用

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

但我怀疑你有一个在线路的问题

memory[0] = "Mem 0"; 

这些不字符串“纪念品0”复制到你的记忆阵列。他们让记忆[我]指向字符串。

您需要将数据用strncpy

例如明确复制 char s =“Mem 0”; strncpy(内存1,s,max(strlen(s)+ 1,29))//最大值30 =(29 char +'\ 0',因为这是你分配的行长度 - 最好是#define this as a恒