我还有另一个C问题,这次我尝试计算每个字符在给定字符串中的出现频率,每个唯一的字符将存储在一个节点结构中,并添加到一个节点结构数组中,以便稍后在霍夫曼编码实现中使用(堆/二叉树已经构建,只是在这些频率方面遇到了问题)。
这是我的代码:
typedef struct node {
unsigned int freq;
char character;
struct node *left, *right;
} node;
//constructor for node struct
node* Node (char c, node* left, node* right){
node* myNode = malloc(sizeof(node));
myNode->freq = 0;
myNode->character = c;
myNode->left = left;
myNode->right = right;
return myNode;
}
node** storeFreq = malloc(sizeof(node) * 256);
char c;
int totalNumOfCharacters = 0;
//read the file character by character
while ((c = fgetc(inputFile)) != EOF && c != '\n')
{
printf("%c\n", c);
if (totalNumOfCharacters == 0) {
//make the node
node* myNode = Node(c, NULL, NULL);
//put it in the list
storeFreq[0] = myNode;
//increase the frequency of the character by one
storeFreq[0]->freq++;
//increase the total character count
totalNumOfCharacters++;
}
else {
for (int i = 0; i < totalNumOfCharacters; i++){
//if the character is already in the table
if (storeFreq[i]->character == c){
//increase the frequency of the character by one
storeFreq[i]->freq++;
}
//if it's not in the table
else {
//make the node
node* myNode = Node(c, NULL, NULL);
//put it in the list
storeFreq[totalNumOfCharacters - 1] = myNode;
//increase the frequency of the character by one
storeFreq[i]->freq++;
//increase the total character count
totalNumOfCharacters++;
}
}
}
}
fclose(inputFile);
//print frequencies
int i = 0;
while (i < totalNumOfCharacters) {
printf("i: %d", i);
printf("Character: %c | Frequency: %d\n", storeFreq[i]->character, storeFreq[i]->freq);
i++;
}
以下是valgrind输出:
==292846== Memcheck, a memory error detector
==292846== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==292846== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==292846== Command: ./a.out encode message.txt message_codeTable.txt
==292846==
T
h
==292846== Use of uninitialised value of size 8
==292846== at 0x1095F4: main (file.c:181)
==292846==
==292846== Invalid read of size 1
==292846== at 0x1095F4: main (file.c:181)
==292846== Address 0x4 is not stack'd, malloc'd or (recently) free'd
==292846==
==292846==
==292846== Process terminating with default action of signal 11 (SIGSEGV)
==292846== Access not within mapped region at address 0x4
==292846== at 0x1095F4: main (file.c:181)
==292846== If you believe this happened as a result of a stack
==292846== overflow in your program's main thread (unlikely but
==292846== possible), you can try to increase the size of the
==292846== main thread stack using the --main-stacksize= flag.
==292846== The main thread stack size used in this run was 8388608.
==292846==
==292846== HEAP SUMMARY:
==292846== in use at exit: 15,880 bytes in 6 blocks
==292846== total heap usage: 6 allocs, 0 frees, 15,880 bytes allocated
==292846==
==292846== LEAK SUMMARY:
==292846== definitely lost: 0 bytes in 0 blocks
==292846== indirectly lost: 0 bytes in 0 blocks
==292846== possibly lost: 0 bytes in 0 blocks
==292846== still reachable: 15,880 bytes in 6 blocks
==292846== suppressed: 0 bytes in 0 blocks
==292846== Reachable blocks (those to which a pointer was found) are not shown.
==292846== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==292846==
==292846== Use --track-origins=yes to see where uninitialised values come from
==292846== For lists of detected and suppressed errors, rerun with: -s
==292846== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
我如何跟踪这个分段错误?我需要一个健全的检查。
3条答案
按热度按时间gz5pxeao1#
检查以下行:
对于像malloc这样的每一次内存分配,都应该释放已经分配的内存字节,以便编译器可以使用这些字节。
如果你举个例子:
在程序完成之前,应该执行
free(node)
,这样就不会发生内存泄漏对于分段错误,您可能试图访问一些无效的内存地址,我还建议使用调试器,因为它在这种情况下确实很有帮助
b5lpy0ml2#
我想出来了,应该加到totalNum而不是totalNum - 1。
zf9nrax13#
此处:
你使用
i
作为索引,它已经运行到数组的末尾,你的意思是: