指向结构的C指针数组realloc()错误
我正在尝试制作一个霍夫曼代码来练习C编码,并且我仍然保持同样的错误.
让我解释一下代码. struct sNo { int valor; char letra; struct sNo *esq; struct sNo *dir; }; typedef struct sNo sNo; 然后它创建一个结构数组(‘否’): sNo *No; No = calloc(qtd_no,sizeof(sNo)); 它从键盘中读取一个字符串,在该数组中放置字母和它出现的次数.就像下面的代表’abracadabra’一样: No: a/5 b/2 r/2 c/1 d/1 现在,要创建一个Huffman树,我需要创建另一个数组(‘pNo’),并指向原始数组: int qtd_pno = qtd_no; sNo **pNo; pNo = calloc(qtd_pno,sizeof(sNo*)); for (i = 0; i < qtd_pno; i++){ pNo[i] = &No[i]; } 这两个数组看起来像这样: No: a/5 b/2 r/2 c/1 d/1 pNo: a/5 b/2 r/2 c/1 d/1 之后,它可以像下面那样对指针数组进行排序而不更改原始指针: No: a/5 b/2 r/2 c/1 d/1 pNo: c/1 d/1 r/2 b/2 a/5 但是当它试图增加’No’数组的大小时…… qtd_no++; No = realloc(No,(sizeof(sNo) * qtd_no)); …这是数组发生的事情: No: a/5 b/2 r/2 c/1 d/1 /0 pNo: c/1 d/1 r/2 b/2 /0 或类似的东西: No: a/5 b/2 r/2 c/1 d/1 /0 pNo: c/1 d/1 r/2 b/2 ?/1288268632 请注意,我没有更改’pNo’数组中的任何内容,但不知何故,指向的值是.我认为它可能是动态内存分配的一些特定特性,但我不确定. 编辑 #include <stdio.h> #include <stdlib.h> #include <string.h> //Definicao do tipo struct No struct sNo { int valor; char letra; struct sNo *esq; struct sNo *dir; }; typedef struct sNo sNo; //Funcoes void SelectionSort(sNo *A[],int qtd_no); void ImprimeArvore (sNo *a); int main(){ //Variaveis auxiliares int i,j; //Leitura de texto do teclado char texto[30]; printf("Digite frase n"); setbuf(stdin,NULL); fgets(texto,30,stdin); //Criacao dos nos int qtd_no = 0; sNo *No; for(i = 0; i < strlen(texto) && texto[i] != ' '; i++){ if(texto[i] >= 32){ if(i == 0){ qtd_no++; No = calloc(qtd_no,sizeof(sNo)); if(No == NULL){ printf("Erro: memoria insuficienten"); exit(1); } No[i].letra = texto[i]; No[i].valor = 1; No[i].esq = NULL; No[i].dir = NULL; printf("%dt%c %ct%dn",i,texto[i],No[i].letra,No[i].valor); }else{ for(j = 0; j <= qtd_no - 1; j++){ if(texto[i] == No[j].letra){ No[j].valor++; printf("%d %dt%c %ct%dn",j,No[j].letra,No[j].valor); break; } else if(j == qtd_no - 1){ qtd_no++; No = realloc(No,(sizeof(sNo) * qtd_no)); if(No == NULL){ printf("Erro: memoria insuficienten"); exit(1); } No[j+1].letra = texto[i]; No[j+1].valor = 1; No[j+1].esq = NULL; No[j+1].dir = NULL; printf("%d %dt%c %ct%dn",No[j+1].letra,No[j+1].valor); break; } } } } } //Criacao de array com ponteiros para nos int qtd_pno = qtd_no; sNo **pNo; pNo = calloc(qtd_pno,sizeof(sNo*)); if(pNo == NULL){ printf("Erro: memoria insuficienten"); exit(1); } for (i = 0; i < qtd_pno; i++){ pNo[i] = &No[i]; } //Organizacao dos nos pelo valor SelectionSort(pNo,qtd_pno); //Criacao da arvore binaria while(qtd_pno > 1){ qtd_no++; No = realloc(No,(sizeof(sNo) * qtd_no)); if(No == NULL){ printf("Erro: memoria insuficienten"); exit(1); } No[qtd_no - 1].letra = ' '; No[qtd_no - 1].valor = (pNo[0]->valor) + (pNo[1]->valor); No[qtd_no - 1].esq = pNo[0]; No[qtd_no - 1].dir = pNo[1]; if(qtd_pno > 2){ for(i = 0; i <= qtd_pno-2; i++){ pNo[i] = pNo[i+2]; } } qtd_pno--; pNo = realloc(pNo,(sizeof(sNo*) * qtd_pno)); pNo[qtd_pno - 1] = &No[qtd_no - 1]; if(qtd_pno > 1){ SelectionSort(pNo,qtd_pno); } } sNo *raiz; raiz = pNo[0]; free(pNo); printf("n%sn",texto); ImprimeArvore(raiz); printf("n"); } //Funcao de organizacao por valor void SelectionSort(sNo *A[],int qtd_pno){ sNo *temp; int i,Imin; for(i = 0; i < qtd_pno - 1; i++){ Imin = i; for(j = i + 1; j < qtd_pno; j++){ if((A[j]->valor) < (A[Imin]->valor)){ Imin = j; } } temp = A[Imin]; A[Imin] = A[i]; A[i] = temp; } } void ImprimeArvore(sNo *a){ if(a->letra) printf ("<%c/%d",(a->letra),(a->valor)); else printf ("<_/%d",(a->valor)); if(a->esq != NULL) ImprimeArvore (a->esq); if(a->dir != NULL) ImprimeArvore (a->dir); printf (">"); } 解决方法
您的方法的问题是realloc无法保证扩展您的阵列.
由于您在其他struct sNo对象中有指向calloc-ed数组的指针,因此在具有这些结构的块上调用realloc可能会使这些结构的所有外部指针无效.这就是为什么你的代码在调用realloc后会遇到未定义的行为. 解决此问题的一种方法是存储索引而不是指针.只要您保留一个添加新项目的动态数组,但从不从中删除项目,这就可以. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |