我有一个必须是白痴的问题,但我不明白为什么。 主要代码到达" 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))
答案 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
保留堆栈中的内存,并通过&
将指针传递给方法,并分配适当的内存 - 在这种情况下,您不需要释放内存,因为它是一旦声明变量的方法返回,就自动释放。