程序在初始化变量时停止响应

时间:2014-11-15 18:05:07

标签: c initialization

我有一个必须是白痴的问题,但我不明白为什么。 主要代码到达" 2测试"打印然后在l-> n = 0时停止响应; 这是我在C中的第一个(真实的)程序,所以我的知识很少。

main.c中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "list.h"

int main(){
    TList* l;
    FILE* txt = fopen("arqtxt.txt", "r");
    char aux[80];
    int c = fgetc(txt), x = 0;

    printf("1test");
    TList_Init(l);
    printf("6test");
    while ((c = fgetc(txt)) != EOF){
        printf("%d",c);
        while (!(isalpha(c))) c = fgetc(txt);
        if (isupper(c)) c = c+32;
        if (islower(c)) aux[x++] = (char) c;
        else{
            TList_Insert(l, aux);
            strcpy(aux, "");
        }
    }
    TList_Print(l);
    getchar();
    return 0;
}

list.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

void TList_Init (TList* l){
    printf("2test");
    l->n = 0;
    printf("3test");
    l->tam = 100;
    printf("4test");
    l->v = malloc(sizeof(TItem)*l->tam);
    printf("5test");

}int TList_Search (TList* l, char* c){
    int i;
    for (i = l->n-1; i >= 0; i--)
        if (strcmp(l->v[i].chave, c) == 0) return i;
    return -1;
}

void InsertSort (TItem* v, int n){
    int i,j;
    TItem aux;
    for (i = 1; i < n; i++){
        aux = v[i];
        j = i-1;
        while (j >= 0 && strcmp(aux.chave, v[j].chave) < 0){
            v[j+1] = v[j];
            j--;
        }
        v[j+1] = aux;
    }
}
void TList_Insert (TList* l, char word[80]){
    if (l->n == l->tam){
        l->tam += 100;
        l->v = realloc(l->v, sizeof(TItem)*l->tam);
    }
    char* c = malloc(sizeof(char)*strlen(word));
    c = word;
    int aux = TList_Search(l, c);
    if (aux != -1){
        l->v[aux].no++;
        return;
    }
    l->v[l->n].chave = c;
    l->v[l->n].no = 1;
    l->n++;
    InsertSort(l->v, l->n);
}



void TList_Print (TList* l){
    int x;
    for (x = 0; x <= l->n; x++)
        printf("%s - %d", l->v[x].chave, l->v[x].no);
}

list.h:

#ifndef LIST_H_
#define LIST_H_

typedef struct Item{
    char* chave;
    int no;
} TItem;

typedef struct List{
    TItem* v;
    int n, tam;
} TList;

void TList_Init (TList*);
void TList_Insert (TList*, char[]);
void TList_Print (TList*);

#endif

输出:

||=== Build: Debug in EP1 (compiler: GNU GCC Compiler) ===|
C:\Users\Lucas\Desktop\EP1\main.c||In function 'main':|
C:\Users\Lucas\Desktop\EP1\main.c|13|warning: 'l' is used uninitialized in this function [-Wuninitialized]|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
||=== Run: Debug in EP1 (compiler: GNU GCC Compiler) ===|

-------------- Run: Debug in EP1 (compiler: GNU GCC Compiler)---------------

Checking for existence: C:\Users\Lucas\Desktop\EP1\bin\Debug\EP1.exe
Executing: "C:\Program Files (x86)\CodeBlocks/cb_console_runner.exe" "C:\Users\Lucas\Desktop\EP1\bin\Debug\EP1.exe"  (in C:\Users\Lucas\Desktop\EP1\.)
Process terminated with status -1073741510 (0 minute(s), 9 second(s))

2 个答案:

答案 0 :(得分:2)

在将指针l传递给TList_Init(l);之前,永远不会初始化指针l->n。然后分配到TList_Init()导致C语言标准中的未定义行为,因为您使用的是不确定的值。

如果让TList *TList_Init (void) { TList *l; l = malloc (sizeof *l); /* Check l != NULL here ... omitted. */ printf("2test\n"); l->n = 0; printf("3test\n"); l->tam = 100; printf("4test\n"); l->v = malloc(sizeof(TItem) * l->tam); printf("5test\n"); return l; } 返回 ptr-to-TList 呢?

{{1}}

答案 1 :(得分:2)

扩展Jens的正确答案:TList* l;初始化一个指向内存中地址的指针 - 它不会为TList本身分配内存,所以l很可能指向一些随机的内存块您无权访问。

您必须致电

l = malloc(sizeof(*l))

保留记忆。一旦完成,请记得致电free(l);

或者声明l不是指针,而是TList:

TList l;
[...]
TList_Init(&l);

这会为TList保留堆栈中的内存,并通过&将指针传递给方法,并分配适当的内存 - 在这种情况下,您不需要释放内存,因为它是一旦声明变量的方法返回,就自动释放。