使用双指针的问题

时间:2014-02-25 16:32:54

标签: c pointers

我是C的新手,无法绕过双指针并且不断出现分段错误错误。我已经调试了一下程序并找到了出错的地方,但是我不能为我的生活找出原因。我会先发布我的代码:

int main() { 
    printf("Enter string to be split: \n");
    a = readline();
    String *st = newString(a);
    String **split;
    int num;
    num = string_split(st, ',', split);
    for (i=0; i<num; i++) { print_string(*(split+i)); }
}

readline()生成一个指向字符数组的指针(由用户输入)并向其追加'\ 0'。 newString和print_string肯定有用。这是string的结构:

typedef struct {
    char *chars;
    int length;
    int maxSize;
} String;

这是string_split的代码,它给我带来了所有麻烦。

int string_split(String *s, char delim, String **arrayOfStructs) {
    char *c = getCharacters(s);
    int len = length(s);
    int begin = 0;
    int end;

    int arraycount = 0;
    String **temp = (String**)malloc(sizeof(String*));

    for (end=0; end<len+1; end++) {
        if ((*(c+end) == delim || *(c+end) == '\0') && begin != end) {
            String *st = substring(s,begin,end-1);
            *(temp + arraycount) = st;
            begin = end + 1;
            arraycount++;
            temp = (String**)realloc(temp, 1+arraycount*sizeof(String*));
        }
    }

    arrayOfStructs = temp;
    return arraycount;
}

总的来说,当我回归分裂时,它所指向的所有String *也都消失了。当print_string获取单个String *并尝试抓取其中一个成员时,会发生分段错误。我不明白为什么,因为我觉得每次必要时都会分配内存,但我觉得我错过了什么。另外,在调试的时候,如果我单步执行string_split,就会产生与我期望的完全相同的temp,所以我认为我不是在我应该的某个地方进行malloc'ing并且它不是函数逻辑的问题。这是substring中的代码,虽然我很确定它是有效的,因为我已经能够从substring返回String *并将它们传递给print_string就好了。

String *substring(String *s1, int begin, int end) {
    String *s = (String*)malloc(sizeof(String));
    int length = 0;
    s->maxSize = 20;
    char *temp = (char*)malloc(20*sizeof(char));
    char *arr = s1->chars;

    int i;
    for (i=begin; i <= end; i++) {
        *(temp+length) = *(arr+i);
        length++;

        if (length == s1->maxSize-1) {
            s1->maxSize = s1->maxSize+20;
            temp = (char*)realloc(temp, s1->maxSize*sizeof(char));
        }
    }
    *(temp+length) = '\0';
    s->length = length;
    s->chars = temp;    
    return s;
}

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

您需要通过引用传递参数arrayOfStructs 而不是值。由于C实际上没有正确的引用,您必须将指针传递给变量:

int string_split(String *s, char delim, String ***arrayOfStructs) {
    ...

    *arrayOfStructs = temp;
    return arraycount;
}

使用地址操作符&

来调用它
num = string_split(st, ',', &split);

现在,您通过值传递参数,这意味着变量arrayOfStructs只是函数内的本地副本。对它的任何更改只对副本进行,并且在函数返回时变量超出范围时会丢失。

答案 1 :(得分:0)

  String **temp = (String**)malloc(sizeof(String*));

  *(temp + arraycount) = st;

temp + arraycount将在内存中为您提供随机地址。 temp包含你刚刚malloced的指针,它应该指向另一个指针。(你还没有初始化),但你正在递增指针,所以你松开了你刚刚进行了malloced的位置。

temp没有指向连续的内存,它专门指向另一个指针(在64位机器上是8字节)