添加动态变量时使用C列表的堆栈溢出

添加动态变量时使用C列表的堆栈溢出,c,list,stack-overflow,dynamic-memory-allocation,C,List,Stack Overflow,Dynamic Memory Allocation,我在学校的一个项目上遇到了一些麻烦 我需要做的很简单,我只需要在列表中添加一些数据。 我通常知道怎么做,但内存分配是动态的这一事实让我感到困惑 下面是清单: typedef struct cList { char *concept; // the concept learned char *sentence; // the sentence associated with the concept int timesUsed; //no of times the concept was used

我在学校的一个项目上遇到了一些麻烦

我需要做的很简单,我只需要在列表中添加一些数据。 我通常知道怎么做,但内存分配是动态的这一事实让我感到困惑

下面是清单:

typedef struct cList {
char *concept; // the concept learned
char *sentence; // the sentence associated with the concept
int timesUsed; //no of times the concept was used to an answer
char learnedFrom[5]; //learned either from "file" or "kbrd"
struct cList *next;
} conceptList;
void insert(char *concept, char *sentence, int timesUsed, char learnedFrom[5]) 
{
    int flag = 0, temp; 

    struct cList *link = (struct cList*) malloc(sizeof(struct cList));

    if(link!=NULL)
    {
        strcpy(link->concept,concept); //this is where the stack overflow happens first.
        strcpy(link->sentence,sentence);
        link->timesUsed = timesUsed;
        strcpy(link->learnedFrom,learnedFrom);

        link->next = head;
        head = link;

        temp = rand()%5;
        if(temp==0)
            printf("3B$ It sure is great to know everything about %s.\n", concept);
        else if(temp==1)
            printf("3B$ This information about %s is quite interesting.", concept);
        else if(temp==2)
            printf("3B$ I have to admit, learning about %s is much more interesting than it seems.", concept);
        else if(temp==3)
            printf("3B$ Learning about %s wasn't even a challenge.", concept);
        else if(temp==4)
            printf("3B$ Wow, learning about %s was so exciting!", concept);
    }
    else
        printf("3B$ Memory not available!!!\n");
}
以及将新数据添加到列表中的函数:

typedef struct cList {
char *concept; // the concept learned
char *sentence; // the sentence associated with the concept
int timesUsed; //no of times the concept was used to an answer
char learnedFrom[5]; //learned either from "file" or "kbrd"
struct cList *next;
} conceptList;
void insert(char *concept, char *sentence, int timesUsed, char learnedFrom[5]) 
{
    int flag = 0, temp; 

    struct cList *link = (struct cList*) malloc(sizeof(struct cList));

    if(link!=NULL)
    {
        strcpy(link->concept,concept); //this is where the stack overflow happens first.
        strcpy(link->sentence,sentence);
        link->timesUsed = timesUsed;
        strcpy(link->learnedFrom,learnedFrom);

        link->next = head;
        head = link;

        temp = rand()%5;
        if(temp==0)
            printf("3B$ It sure is great to know everything about %s.\n", concept);
        else if(temp==1)
            printf("3B$ This information about %s is quite interesting.", concept);
        else if(temp==2)
            printf("3B$ I have to admit, learning about %s is much more interesting than it seems.", concept);
        else if(temp==3)
            printf("3B$ Learning about %s wasn't even a challenge.", concept);
        else if(temp==4)
            printf("3B$ Wow, learning about %s was so exciting!", concept);
    }
    else
        printf("3B$ Memory not available!!!\n");
}

在第一个
malloc
之后,
concept
成员具有非序列化值

您需要为传递的字符串分配空间,然后才能

strcpy(link->concept,concept);
所以你需要

link->concept = malloc(strlen(concept)+1);
if (link->concept != NULL)
{
    strcpy(link->concept,concept);
}
else
{
    free(link)
    return;
}

对于
句子
成员也一样。

您需要分配
链接->概念
链接->句子
(参见第7行)。或者将它们声明为数组(
char-concept[100]
而不是
char*concept

重要提示:请始终使用
strncpy
而不是
strcpy

void insert(char *concept, char *sentence, int timesUsed, char learnedFrom[5]) 
{
    int flag = 0, temp; 

    struct cList *link = (struct cList*) malloc(sizeof(struct cList));

    // Add these:
    link->concept = malloc...
    link->sentence = malloc...

    if(link!=NULL)
    {
        strcpy(link->concept,concept); //this is where the stack overflow happens first.
        strcpy(link->sentence,sentence);
        link->timesUsed = timesUsed;
        strcpy(link->learnedFrom,learnedFrom);

        link->next = head;
        head = link;

        temp = rand()%5;
        if(temp==0)
            printf("3B$ It sure is great to know everything about %s.\n", concept);
        else if(temp==1)
            printf("3B$ This information about %s is quite interesting.", concept);
        else if(temp==2)
            printf("3B$ I have to admit, learning about %s is much more interesting than it seems.", concept);
        else if(temp==3)
            printf("3B$ Learning about %s wasn't even a challenge.", concept);
        else if(temp==4)
            printf("3B$ Wow, learning about %s was so exciting!", concept);
    }
    else
        printf("3B$ Memory not available!!!\n");
}

分配的结构中的
概念
句子
指针尚未初始化。因此,当您使用strcpy时,您正在取消对未初始化指针的引用。这将调用在本例中导致程序崩溃的

您需要做的是为这些指针分配空间,然后执行复制:

link->concept = malloc(strlen(concept) + 1);
strcpy(link->concept,concept);
您也可以使用
strdup
一步完成此操作:

link->concept = strdup(concept);

strcpy(链接->概念,概念)-->
link->concept=malloc(strlen(concept)+1);strcpy(链接->概念,概念)不为结构中的指针分配内存。你试图使用他们指向的记忆,这些记忆会导致无法定义的行为,而这些行为可以做任何事情。查找
strdup
并记住释放内存。当您分配结构时,它不会为“概念”和“句子”分配空间。这意味着当你试图写到这些位置时,它会崩溃。好的,谢谢大家帮助我解决这个问题。非常感谢抱歉,但我不能同意你的笼统建议,即避免使用strcpy()
而使用strncpy()
。必须确保避免超出目标数组的界限,但使用
strncpy()
这样做有其自身的相关问题
strncpy()
不是万灵丹。如果您的sdk支持它,它只是@0andriy
strdup()
。建议的解决方案在malloc可用的情况下始终有效。您能指出至少一个在21世纪不可用的解决方案吗?那么,gcc标志与C库有什么关系呢?你的意思是你的代码将使用内部函数?好吧,看起来你只是在猜测,在常用的SDK中没有。我已经说完了,如果你想改变我的想法,请说得更准确些。