【问题标题】:C array being overwritten/deleted? very confusedC 数组被覆盖/删除?很混乱
【发布时间】:2014-12-14 06:10:22
【问题描述】:

我正在使用 C 语言开发一个项目,它运行良好,除了一个函数似乎覆盖了我的数组并写入了奇怪的数字,例如 1970802352,它记录了文件中出现的单词

这是我的头文件:

#ifndef LIST_H
#define LIST_H
struct Node_{
        char* word;
        //array holding names of files word occurs in 
        char **filesIn;
        int numFilesIn;
        //array holding count of how many times word occured in file
        int* occursIn;
        struct Node_ *next;
        int isHead;
};

typedef struct Node_ Node;

int insert(char *wordToAdd, char *File);

int addOccur(Node *addedTo, char *File);

Node *createNode(char *wordToAdd, char *File);

void destroyNodes();

#endif

这是不断覆盖数组的函数:

Node *head;
int insert(char *wordToAdd, char *File){
        if(head == NULL){
                Node *new;
                new = createNode(wordToAdd, File);
                new->isHead = 1;
                head = new;
                return 0;
        }
        else{
                Node *trace;
                trace = head;
                char *traceWord;
                int wordSize;
                wordSize = strlen(trace->word);
                traceWord = (char*) malloc(wordSize + 1);
                strcpy(traceWord, trace->word);
                int a =strcmp(wordToAdd, traceWord);
                free(traceWord);
                if(a == 0){
                        int b = addOccur(trace, File);
                        //printf("addOccur returned %d\n", b);
                        return 0;
                }
                if(a < 0){
                        Node *Insert = createNode(wordToAdd, File);
                        trace->isHead = 0;
                        Insert->isHead = 1;
                        Insert->next = trace;
                        head = Insert;
                        return 0;
                }
                else{


                        Node *backTrace;
                        backTrace = head;

                        while(trace->next != NULL){
                                trace = trace->next;
                                traceWord = trace->word;
                                a = strcmp(wordToAdd, traceWord);
                                if(a < 0){
                                        Node* Insert = createNode(wordToAdd, File);
                                        Insert->next = trace;
                                        backTrace->next = Insert;
                                        return 0;
                                }
                                if(a == 0){
                                        addOccur(trace, File);
                                        //free(wordToAdd);
                                        return 0;
                                }
                                if(a > 0){
                                        backTrace = trace;
                                        continue;
                                }
                        }
                        Node *Insert = createNode(wordToAdd, File);
                        trace->next = Insert;
                        return 0;
                }
        }
        return 1;
}

其他功能是:

Node* createNode(char *wordToAdd, char *File){
        Node *new;
        new =   (Node*)malloc(sizeof(Node));
        memset(new, 0, sizeof(Node));
        new->word = wordToAdd;
        char **newArray;
        newArray = (char**)malloc(sizeof(char*));
        newArray[0] = File;
        new->filesIn = newArray;
        int a[1];
        a[0] = 1;
        new->occursIn = a;
        //new->occursIn[0] = 1;
        new->numFilesIn = 1;
        return new;
}

int addOccur(Node *addedTo, char *File){

        char **fileList = addedTo->filesIn;
        char *fileCheck;
        int i = 0;
        int fileNums = addedTo->numFilesIn;
        for(i = 0; i < fileNums; i++){
                fileCheck = fileList[i];
                if(strcmp(fileCheck, File) == 0){
                        int *add1;
                        add1 = addedTo->occursIn;
                        int j = add1[i];
                        j++;
                        add1[i] = j;
                        return 0;
                }
        }

        int numberOfFilesIn;
        numberOfFilesIn = addedTo->numFilesIn;
        char **newList = (char**)malloc(sizeof(char*) * numberOfFilesIn + sizeof(char*));
        i = 0;
        char *dest;
        char *src;
for(i = 0; i < numberOfFilesIn; i++){
                src = fileList[i];
                int len;
                len = strlen(src);
                dest = (char*)malloc(sizeof(char) * (len + 1));
                strcpy(dest, src);
                newList[i] = dest;
                }
        int len2;
        len2 = strlen(File);
        newList[i] = File;
        free(fileList);
        int r = addedTo->numFilesIn;
        r++;
        addedTo->numFilesIn = r;
        addedTo->filesIn = newList;
        i = 0;
        int *g;
        g =  addedTo->occursIn;
        int count2;
        count2 = addedTo->numFilesIn;
        count2++;
        int a[count2];
        for(i = 0; i < count2 -1; i++){
                a[i] = g[i];
        }
        a[count2 - 1] = 1;
        return 0;
}

当去 gdb 时,我注意到

head->occursIn[0]

行后变化

wordSize = strlen(trace->word);

我不知道为什么。

【问题讨论】:

  • 优化是否会发生这种情况?如果是这样,那么调试器可能无法可靠地确定准确的错误行。如果执行这一行真的改变了一些完全不相关的东西,那就太奇怪了。我的意思是即使你在某处混淆了指针,我认为strcmp 不会触及任何东西。所以a 需要与head-&gt;occursIn[0] 在同一个地方。我知道,对于这种奇怪现象,只有其他选择是 UB 和/或堆栈损坏。
  • @luk32 是的,它发生在优化开启和关闭的情况下,写错了它发生的地方并更正了它。我注意到我的代码似乎适用于除头部之外的每个节点。
  • 请显示您的函数 createNode() 和 addOccur() 的代码。
  • @RichardSchwartz 好的,我把它放了

标签: c arrays pointers nodes overwrite


【解决方案1】:

在您的 CreateNode() 函数中,您没有为发生的数组分配存储空间。您只是在函数中声明一个本地数组,然后分配发生的指针:

int a[1];
a[0] = 1;
new->occursIn = a;

当 createNode 函数返回时,数组 a[1] 消失,所以此时你的occurrenceIn 指针指向一个可能被覆盖的值。

即使在 createNode 中正确分配了存储空间,您也已为数组设置了固定大小,但您的整个策略取决于该数组对每个文件都有一个元素;在 addOccurs 中,您无需为新文件分配新的更大数组。

您可能需要重新评估您的策略并改用列表而不是数组。

【讨论】:

  • 好吧,现在考虑一下,列表可能更容易实现。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-31
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 2012-05-09
相关资源
最近更新 更多