【问题标题】:Segmentation fault 11, despite plenty of memory being allocated分段错误 11,尽管分配了大量内存
【发布时间】:2015-04-21 17:52:57
【问题描述】:

我遇到了一个奇怪的错误。当我编译我的代码时,它给了我以下信息:

%i??
[R?
R?
?
Desktop/prog2
Terminal
51/sls2t0f16cd4dzl3640n4p2w0000gn/T/
private/tmp/com.apple.launchd.AJrzeyltFv/Render
ION=343.6
ER=Frank
Listeners
in:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/git/bin
ank
E=/Users/Frank
nk/Desktop/prog2

Segmentation fault: 11
logout

我了解这是由于内存问题造成的。但是我给dictionary2和原来的dictionary一样的内存,为什么它不能编译整个列表呢?

这是我的代码(我知道这有点冗长,但我觉得有必要传达正在发生的事情):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>

struct entry
{
    char word[15];
    char definition[50];
};


void dictionarySort(struct entry dictionary[]) {
    int i, j, k, word1, word2, dict2Length = 1;
    bool bnf = false;
    struct entry dictionary2[100] = {{}};

    for (i = 0; i <= strlen(&dictionary->word[0]); i++) {
        strcpy(&dictionary2[0].word[i], &dictionary[0].word[i]);
    }


    i = 0;
    word1 = 1;
    word2 = 0;



    while (isalpha(dictionary[word1].word[0])) {

        while (i <= strlen(&dictionary->word[word1])) {
            //printf("%c", dictionary[word1].word[i]);
            if (dictionary[word1].word[i] == dictionary2[word2].word[i]) {
                i++;
                bnf = false;
            }
            else if (dictionary[word1].word[i] < dictionary[word2].word[i]) {
                //insert section to prevent back-and-forth cycling
                if (bnf == false) {
                    word2--;
                    bnf = true;
                }
                else { //(dictionary[word1].word[i] < dictionary[word2].word[i])
                    //open up new index by moving everything above up one, insert at word
                    for (j = dict2Length; j > word2; j--) {
                        //word
                        for (k = 0; k <= strlen(&dictionary2->word[0]); k++) {
                            strcpy(&dictionary2[j+1].word[k], &dictionary2[j].word[k]);
                        }
                        //definition
                        for (k = 0; k <= strlen(&dictionary2->word[0]); k++) {
                            strcpy(&dictionary2[j+1].definition[k], &dictionary2[j].definition[k]);
                        }
                    }

                    //for (k = 0; k < strlen(&dictionary1->word[word1]))
                    for (k = 0; k < strlen(dictionary[word1].word); k++) {
                        strcpy(&dictionary2[word2].word[k], &dictionary[word1].word[k]);
                    }
                    for (k = 0; k < strlen(dictionary[word1].definition); k++) {
                        strcpy(&dictionary2[word2].definition[k], &dictionary[word1].definition[k]);
                    }
                    dict2Length++;
                    break;
                }   
            }
            else {
                //insert section to prevent back-and-forth cycling
                if (bnf == false) {
                    word2++;
                    bnf = true;
                }
                else { //(dictionary[word1].word[i] < dictionary[word2].word[i])
                    //open up new index by moving everything above up one, insert at word
                    for (j = dict2Length; j > word2; j--) {
                        //word
                        for (k = 0; k <= strlen(&dictionary2->word[0]); k++) {
                            strcpy(&dictionary2[j+1].word[k], &dictionary2[j].word[k]);
                        }
                        //definition
                        for (k = 0; k <= strlen(&dictionary2->word[0]); k++) {
                            strcpy(&dictionary2[j+1].definition[k], &dictionary2[j].definition[k]);
                        }
                    }

                    for (k = 0; k < strlen(dictionary[word1].word); k++) {
                        strcpy(&dictionary2[word2].word[k], &dictionary[word1].word[k]);
                    }
                    for (k = 0; k < strlen(dictionary[word1].definition); k++) {
                        strcpy(&dictionary2[word2].definition[k], &dictionary[word1].definition[k]);
                    }
                    dict2Length++;
                    break;
                }
            }
        }
        word1++;
    }


    word2 = 0;

    for (i = 0; i < dict2Length; i++) {
        printf ("%s\n", dictionary2[i].word);
    }

}

int main (void) {
    struct entry dictionary[100] = 
    {{"aerie", "a high nest"},
    {"abyss", "a bottomless pit"},
    {"ahoy", "a nautical call of greeting"},
    {"addle", "to become confused"},
    {"aardvark", "a burrowing African mammal"},
    {"agar", "a jelly made of seaweed"},
    {"acumen", "mentally sharp; keen"},
    {"aigrette", "an ornamental cluster of feathers"},
    {"affix", "to attach"},
    {"ajar", "partially opened"}};
    dictionarySort(dictionary);
}

【问题讨论】:

  • 分段错误是内存问题,但不是内存耗尽的问题。这是您的程序尝试访问未分配给它的内存的问题。这通常是由错误的数组索引、未初始化或悬空指针或类似情况引起的。
  • 您可以使用某种调试器吗?程序冻结的位置应该能准确地告诉你问题出在哪里。
  • 您可以使用qsort

标签: c string memory structure


【解决方案1】:

这一行的索引从前到后

strcpy(&dictionary2[0].word[i], &dictionary[0].word[i]);    

应该是

strcpy(&dictionary2[i].word[0], &dictionary[i].word[0]);

甚至更好

strcpy(dictionary2[i].word, dictionary[i].word);

另外,您的循环 for (i...) 基于 strlen(&amp;dictionary-&gt;word[0])。您是否应该将数组条目的数量作为参数传递给dictionarySort()?就目前而言,循环基于第一个字典条目的长度。

我必须继续调试排序。这太可怕了。只需使用qsort()

【讨论】:

    【解决方案2】:

    使用qsort

    void dictionarySort(struct entry dictionary[]) {
        struct entry dictionary2[100] = {{"",""}};
        int i, n;
    
        for (i = 0; i < 100 && dictionary[i].word[0] != '\0'; ++i){
            dictionary2[i] = dictionary[i];
        }
        n = i;
    
        qsort(dictionary2, n, sizeof(*dictionary2), strcmp);
    
        for (i = 0; i < n; ++i) {
            printf ("%s\n", dictionary2[i].word);
        }
    }
    

    【讨论】:

    • 您的代码在 strcmp 上返回错误。不是需要参数的函数吗?
    • @FrankTocci 我想这可能是一个警告。尝试转换为(int (*)(const void*,const void*))strcmp 或编写包装函数。
    • 包装函数就像int dic_cmp(const void *a, const void *b){ return strcmp((char*)a, (char*)b); }, ... dic_cmp 而不是strcmp
    【解决方案3】:

    您在计算字典长度时似乎遇到了问题。当你运行它时,它说长度类似于 1701996321,这似乎比它应该的要高得多。然后,在最后一个 for 循环中,就在您打印单词的最后,您可能会超出字典的范围。注释掉 printf ,你会看到错误消失了。我会先研究 dict2Lenght。

    for (i = 0; i < dict2Length; i++) {
        printf ("%s\n", dictionary2[i].word);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-28
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 2016-09-29
      • 2017-01-07
      • 1970-01-01
      相关资源
      最近更新 更多