[英]How to solve SIGSEGV, Segmentation fault in C?
我正在開發一個程序,用於從文本文件讀取數據並使用霍夫曼編碼對其進行編碼。 我已經運行了2-3次,它只顯示一條錯誤消息:
Program received signal SIGSEGV, Segmentation fault. __strcpy_sse2 () at ../sysdeps/x86_64/multiarch/../strcpy.S:57 57 ../sysdeps/x86_64/multiarch/../strcpy.S: No such file or directory.
當我調試程序時,我將問題追溯到以下功能:
// walk the tree and put 0s and 1s
void build_bcode_from_tree(node n, char *s, int len)
{
static char *out = buf;
if (n->c) {
s[len] = 0;
strcpy(out, s);
code[n->c] = out;
out += len + 1;
return;
}
s[len] = '0'; build_bcode_from_tree(n->left, s, len + 1);
s[len] = '1'; build_bcode_from_tree(n->right, s, len + 1);
}
我究竟做錯了什么?
這是完整的代碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node_t {
struct node_t *left, *right;
int freq;
char c;
} *node;
struct node_t pool[256] = {{0}};
node qqq[255], *q = qqq - 1;
int n_nodes = 0, qend = 1;
char *code[128] = {0}, buf[1024];
//creating tree
node create_tree(int freq, char c, node a, node b)
{
node n = pool + n_nodes++;
if (freq) n->c = c, n->freq = freq;
else {
n->left = a, n->right = b;
n->freq = a->freq + b->freq;
}
return n;
}
// priority queue according to frequency
void qinsert(node n)
{
int j, i = qend++;
while ((j = i / 2)) {
if (q[j]->freq <= n->freq) break;
q[i] = q[j], i = j;
}
q[i] = n;
}
node qremove()
{
int i, l;
node n = q[i = 1];
if (qend < 2) return 0;
qend--;
while ((l = i * 2) < qend) {
if (l + 1 < qend && q[l + 1]->freq < q[l]->freq) l++;
q[i] = q[l], i = l;
}
q[i] = q[qend];
return n;
}
// walk the tree and put 0s and 1s
void build_bcode_from_tree(node n, char *s, int len)
{
static char *out = buf;
if (n->c) {
s[len] = 0;
strcpy(out, s);
code[n->c] = out;
out += len + 1;
return;
}
s[len] = '0'; build_bcode_from_tree(n->left, s, len + 1);
s[len] = '1'; build_bcode_from_tree(n->right, s, len + 1);
}
// individual binary representation
void ind_repre(const char *s)
{
int i, freq[128] = {0};
char c[16];
while (*s) freq[(int)*s++]++;
for (i = 0; i < 128; i++)
if (freq[i]) qinsert(create_tree(freq[i], i, 0, 0));
while (qend > 2)
qinsert(create_tree(0, 0, qremove(), qremove()));
build_bcode_from_tree(q[1], c, 0);
}
// endode the whole file data
void compress(const char *s, char *out)
{
while (*s) {
strcpy(out, code[*s]);
out += strlen(code[*s++]);
}
}
//showing decode data
void decompress(const char *s, node t)
{
FILE *filew;
filew = fopen("output.txt", "w");
node n = t;
while (*s) {
if (*s++ == '0') n = n->left;
else n = n->right;
// if (n->c) putchar(n->c), n = t;
if (n->c) fprintf(filew,"%c", n->c), n = t;
}
putchar('\n');
if (t != n) printf("wrong input\n");
fclose(filew);
}
// main function
int main(void)
{
int i;
const char *str;
char buff[1024];
// read from file
char txt[1024];
FILE *file;
size_t nread;
file = fopen("index.html", "r");
if (file == NULL) {
printf("There is no file with this name!!\n");
exit(-1);
} else {
while ((nread = fread(txt, 1, sizeof txt, file)) > 0)
fwrite(txt, 1, nread, stdout);
if (ferror(file)) {
}
fclose(file);
}
str = txt;
ind_repre(str);
for (i = 0; i < 128; i++)
if (code[i]) printf("'%c': %s\n", i, code[i]);
compress(str, buff);
printf("compressedData: %s\n", buff);
decompress(buff, q[1]);
printf("decoding done ! check output file\n");
return 0;
}
調試器消息顯示,確實是對strcpy()
的調用才是罪魁禍首:
__strcpy_sse2()位於../sysdeps/x86_64/multiarch/../strcpy.S:57
從您共享代碼,緩沖來看buf
到out
點,似乎沒有大到足以容納長度的字符串len
,您嘗試復制到它。 另外,也可能buf
不在進程內存的可寫部分中。
在任何情況下,請確保out
指向一個可寫緩沖區,該緩沖區足夠大,也許可以通過為其分配一些空間來實現,例如:
static char *out = NULL;
if (out == NULL)
out = malloc(len);
這應該可以解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.