尝试交换字符串内容时出现Seg Fault 11

时间:2014-12-20 08:55:27

标签: c string char segmentation-fault swap

所以我正在尝试创建一个textbuffer,它将给定文本的行存储到列表中。我正在编写交换函数,但是如果我尝试调整某些行,我会遇到分段错误。

这是我正在使用的当前交换功能:

void swapTB (TB tb, int pos1, int pos2) {

if (tb == NULL) {
    abort();
} 

if (pos1 < 0 || pos1>tb->size || pos2<0 || pos2>tb->size) {
    printf("error: lines are out of range!\n");
    abort();
}

link line1 = findLine(tb, pos1);
link line2 = findLine(tb, pos2);

char *temp = (char *)malloc((strlen(line1->line) + 1) * sizeof(char));
strcpy(temp,line1->line);
strcpy(line1->line, line2->line);
strcpy(line2->line,temp);

free(temp);

}

如果我尝试提供此文字:

char text[] = "0. She walks in beauty, like the night\n"
              "1. Of cloudless climes and starry skies;\n"
              "2. And all that’s best of dark and bright\n"
              "3. Meet in her aspect and her eyes;\n"
              "4. Thus mellowed to that tender light\n"
              "5. Which heaven to gaudy day denies.\n"
              "6. One shade the more, one ray the less,\n"
              "7. Had half impaired the nameless grace\n"
              "8. Which waves in every raven tress,\n"
              "9. Or softly lightens o’er her face;\n"
              "10. Where thoughts serenely sweet express,\n";

并进行以下交换:

swapTB(tb, 4, 7);
swapTB(tb, 2, 9);
swapTB(tb, 2, 10);

它工作正常,我得到了这个输出:

0. She walks in beauty, like the night
1. Of cloudless climes and starry skies;
10. Where thoughts serenely sweet express,
3. Meet in her aspect and her eyes;
7. Had half impaired the nameless grace
5. Which heaven to gaudy day denies.
6. One shade the more, one ray the less,
4. Thus mellowed to that tender light
8. Which waves in every raven tress,
2. And all that’s best of dark and bright
9. Or softly lightens o’er her face;

但是,如果我稍微改变文字,例如缩短第9行:

char text[] = "0. She walks in beauty, like the night\n"
              "1. Of cloudless climes and starry skies;\n"
              "2. And all that’s best of dark and bright\n"
              "3. Meet in her aspect and her eyes;\n"
              "4. Thus mellowed to that tender light\n"
              "5. Which heaven to gaudy day denies.\n"
              "6. One shade the more, one ray the less,\n"
              "7. Had half impaired the nameless grace\n"
              "8. Which waves in every raven tress,\n"
              "9. Or softly lightens o’er\n"
              "10. Where thoughts serenely sweet express,\n";

我收到了分段错误11。

这种情况一直在发生,有时它工作正常,有时它会出现分段错误,有时会运行但最终输出有重复 - 这一切都会根据我给出的功能而变化。

顺便说一下,文本存储在这样的结构中:

typedef struct textNode *link;

struct textNode {
    char *line;
    link next;
};

struct textbuffer{
    link head;
    link last;
    int size;
}; 

编辑:

分配换行符的功能:

link newLine(char text[], int start, int i) {

    link newLine = malloc(sizeof(*newLine));
    assert(newLine != NULL);

    newLine->line = extract(text, start, i);
    //printf("newline is %s\n", newLine->line);
    newLine->next = NULL;

    return newLine;

}

提取功能

char* extract(const char* src, int start, int end) {

    return strndup(src + start, (end - start)+1);
}

findLine的功能

link findLine(TB tb, int pos) {

    link curr = tb->head;
    int index = 0;

    while (index != pos) {
        curr = curr->next;
        index++;
    }

    return curr;
}

2 个答案:

答案 0 :(得分:1)

问题似乎是您有时会将较长字符串中的数据写入先前为较短字符串分配的空间中。执行交换的代码,即这五行有问题:

char *temp = malloc(strlen(line1->line) + 1); // No need to cast or multiply by sizeof(char)
strcpy(temp,line1->line);
strcpy(line1->line, line2->line);
strcpy(line2->line,temp);
free(temp);

您的代码确保temp中的line1->line数据中有足够的空间用于temp的数据,但假设line2->line中有line2->line的数据有足够的空间并且line1->linechar *temp = line1->line; line1->line = line2->line; line2->line = temp; 的所有字符都有足够的空间。

要解决此问题,请重新分配指针,或者执行指针交换而不是交换内容,即

{{1}}

答案 1 :(得分:1)

您必须正确编写交换操作。而不是这段代码

char *temp = (char *)malloc((strlen(line1->line) + 1) * sizeof(char));
strcpy(temp,line1->line);
strcpy(line1->line, line2->line);
strcpy(line2->line,temp);

应该有

char *temp  = line1->line;
lin1->line  = line2->line;
line2->line = temp;

如您所见,无需复制字符串本身。交换指针就足够了。

考虑到没有任何意义将数据成员size定义为具有类型int,然后每次检查它是否小于零。如果将大小定义为具有类型size_t

,那会好得多