是什么导致了这个段错误?

时间:2014-08-20 22:59:14

标签: c pointers malloc

[这个问题自昨天以来已被大量编辑。我正在更新以澄清问题。]

我在调用mygets()后得到一个段错误。这是我的代码:

    #include <termios.h>
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct _charlist{
        char ch;
        struct _charlist *next;
    }charlist;

    static struct termios old, new;
    void mygets(char** p);
    char getche(void); 
    char getch_(int echo);
    void resetTermios(void);
    void initTermios(int echo);


    int main(void){
        char *p;

        printf("\nWho loves orange soda?: ");
        mygets(&p);
        printf("'%s' loves orange soda!", p);
    }


    void mygets(char** p){
        char c;
        charlist *root, *curr;
        unsigned i, count=0;

        root=NULL;

    while((c = getche()) != '\n'){      

        count++;    
        if(!root){ 
            root = (charlist*) malloc(sizeof(charlist));
            root->ch = c;
                root->next = NULL;
                curr = root;
            }

            else{
                curr
->next = (charlist*) malloc(sizeof(charlist));
                curr->next->ch = c;
                curr->next->next = NULL;
                curr = curr->next;
            }
        }

        //now request string space.
        *p = (char*) malloc((count+1)*sizeof(char));

        printf("\np is now malloced");      //This line doesn't get printed!

        //move linked list into string space.
        curr = root;
        for(i=0; i<=count; i++){
            *p[i] = curr->ch;
            curr = curr->next;
        }

        //null-terminate the string.
        *p[i] = '\0';

    }

有人能告诉我为什么会出现段错误吗?

除非代码与问题的比率低于某个任意阈值,否则我无法发布此问题。因此,现在遵循爱丽丝梦游仙境的第一段,供您考虑。

  爱丽丝开始厌倦了坐在姐姐身边   银行,无所事事:她偷了一两次   她妹妹正在读书,但没有照片或   其中的对话,&#39;以及书的用途,&#39;爱丽丝想   没有图片或对话?&#39;

4 个答案:

答案 0 :(得分:4)

调用func时,会在p中传递本地变量main副本。然后,此副本将分配到malloc中的func ed区域。 p中的原始main永远不会被修改,因此其内容仍未定义,导致printf解除引用p时出现分段错误,以便打印字符串。

您可能希望func返回指向新malloc'd区域的char*

答案 1 :(得分:1)

您可以通过值将参数传递给函数。所以根据函数声明

void func(char* p);

参数p是函数的局部变量,退出函数后将被销毁。局部变量的任何更改都不会影响参数。

您可以通过以下方式定义功能

char * func(){
    unsigned count = 10;
    char *p = (char*) malloc(sizeof(char)*(count+1));

    //p is given a string after this, but problem is the above line.

   return p;
}

并将其命名为

p = funct();

void func(char ** p){
    unsigned count = 10;
    *p = (char*) malloc(sizeof(char)*(count+1));

    //p is given a string after this, but problem is the above line.
}

并将其命名为

func( &p );

答案 2 :(得分:0)

问题在于:

*p[i] = curr->ch;

应该是:

(*p)[i] = curr->ch;

您想要访问i所指向的p个字符。不取消引用指针数组中的i指针。

稍后与*p[i] = '\0';相同的问题。

你也没有malloc足够的空间,因为你的循环写count + 1个字符然后你写了一个额外的空终止符,所以你应该malloc count + 2或调整你的循环来完成{{1 },而不是i<count。 (可能是后者)。

此外,在解除引用之前检查i<=count非常有用,这样如果您确实有一个错误的错误,那么您就不会得到未定义的行为。

答案 3 :(得分:-2)

免责声明:在此回答时the question didn't even include the real cause of the problem,并且代码足够少,以至于这两项建议都是唯一可能出错的问题。现在OP在夜间的某个时间发布了他的实际代码,它会失效。出于显而易见的原因,请不要基于此进行投票。

-

删除(char*)强制转换。你肯定会得到一个“赋值来自整数而没有强制转换的警告”。

然后#include <stdlib.h>,以便您可以实际使用malloc&amp; co不会因不匹配的函数签名导致未定义的行为。

修改:如果您在func中调用main之前未声明{{1}},则会出现类似的问题。