Wio*_*ooo 2 c valgrind segmentation-fault
我对C很新,今天我被介绍给Valgrind.我安装它并在我的C计算器/方程解析器上运行它,我正在努力弄清楚为什么我有一个分段错误(核心转储),我得到了这个:
==20== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==20== General Protection Fault
==20== at 0x4008E27: _dl_map_object (dl-load.c:2317)
==20== by 0x40014DD: map_doit (rtld.c:642)
==20== by 0x4010193: _dl_catch_error (dl-error.c:187)
==20== by 0x4002169: do_preload (rtld.c:831)
==20== by 0x4002169: handle_ld_preload (rtld.c:929)
==20== by 0x4004DEE: dl_main (rtld.c:1667)
==20== by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==20== by 0x4001BB7: _dl_start_final (rtld.c:347)
==20== by 0x4001BB7: _dl_start (rtld.c:573)
==20== by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==20== by 0x1: ???
==20== by 0x1FFF0008AE: ???
==20== by 0x1FFF0008BB: ???
Run Code Online (Sandbox Code Playgroud)
当然,我不知道它意味着什么,而我发现类似错误的其他事情对我来说没有多大意义.有人能以一种相对简单的方式解释这一点,像我这样的人可以理解吗?
编辑:我尝试通过gdb运行它(由@ pm100建议的屁股),只有这个:
Program received signal SIGSEGV, Segmentation fault.
0x000000000040067b in ?? ()
编辑:因为我的代码被要求,这里是.我可能做错了很多.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void write(char** dest, char* src, int index) {
int i = 0;
for (i = 0; src[i] != '\0'; i++) {
dest[index][i] = src[i];
}
dest[index][i] = '\0';
return;
}
void crite(char** dest, char src, int index) {
int i = 0;
dest[index][0] = src;
dest[index][1] = '\0';
return;
}
void evaluate(char* args) {
int i = 0;
int j = 0;
const char* numbers = "1234567890";
const char* operators = "+-*/";
int chunk = 0;
char** chunks = calloc(24, sizeof(char*));
char* current = calloc(24, sizeof(char));
for (i = 0; strchr("\0\n", args[i]) == NULL; i++) {
//printf("Args[i]:%c\n\n", args[i]);
if (strchr(numbers, args[i]) != NULL) {
//printf("Number added to current: %c\n\n", args[i]);
current[j] = args[i];
//printf("\nCurrent: %s\n", current);
j++;
} else if (strchr(operators, args[i]) != NULL) {
write(chunks, current, chunk);
chunk++;
crite(chunks, args[i], chunk);
chunk++;
j = 0;
free(current);
current = calloc(24, sizeof(char));
//printf("Terminated with operator and operator added.\n\n");
} else {
printf("ERROR: Encountered invalid token.\n\n");
return;
}
}
for (i = 0; chunks[i] != NULL; i++)
//printf("\n-Chunk: %s\n\n", chunks[chunk]);
return;
}
int main(int argc, char** argv) {
evaluate(argv[1]);
}
Run Code Online (Sandbox Code Playgroud)
我用来编译它的命令是 gcc calculator.c -g -o calculator
示例命令: ./calculator 1*2
更新:Valgrind的问题是由我使用的Windows子系统引起的,所以只要你在linux上运行Valgrind就应该没问题.我在虚拟机中尝试过它并且有效.
另外,感谢帮助我修复我的分段错误,即使这不是最初的问题:)
在valgrind下运行此代码会导致以下结果:
[dbush@db-centos ~]$ valgrind /tmp/x1 1*2
==1431== Memcheck, a memory error detector
==1431== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==1431== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==1431== Command: /tmp/x1 1*2
==1431==
==1431== Invalid write of size 1
==1431== at 0x80484B3: write (x1.c:8)
==1431== by 0x80485E8: evaluate (x1.c:39)
==1431== by 0x804869D: main (x1.c:61)
==1431== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1431==
==1431==
==1431== Process terminating with default action of signal 11 (SIGSEGV)
==1431== Access not within mapped region at address 0x0
==1431== at 0x80484B3: write (x1.c:8)
==1431== by 0x80485E8: evaluate (x1.c:39)
==1431== by 0x804869D: main (x1.c:61)
==1431== If you believe this happened as a result of a stack
==1431== overflow in your program's main thread (unlikely but
==1431== possible), you can try to increase the size of the
==1431== main thread stack using the --main-stacksize= flag.
==1431== The main thread stack size used in this run was 10485760.
==1431==
==1431== HEAP SUMMARY:
==1431== in use at exit: 120 bytes in 2 blocks
==1431== total heap usage: 2 allocs, 0 frees, 120 bytes allocated
==1431==
==1431== LEAK SUMMARY:
==1431== definitely lost: 0 bytes in 0 blocks
==1431== indirectly lost: 0 bytes in 0 blocks
==1431== possibly lost: 0 bytes in 0 blocks
==1431== still reachable: 120 bytes in 2 blocks
==1431== suppressed: 0 bytes in 0 blocks
==1431== Rerun with --leak-check=full to see details of leaked memory
==1431==
==1431== For counts of detected and suppressed errors, rerun with: -v
==1431== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 13 from 8)
Run Code Online (Sandbox Code Playgroud)
所以在这一行write:
dest[index][i] = src[i];
Run Code Online (Sandbox Code Playgroud)
您正在取消引用NULL指针并尝试在那里写入.有问题的NULL指针是dest[index],因为您曾经calloc分配内存,所以它是NULL .这是你做了什么:
char** chunks = calloc(24, sizeof(char*));
char* current = calloc(24, sizeof(char));
Run Code Online (Sandbox Code Playgroud)
您创建chunks指针数组,但没有为这些指针指定任何内容.您需要遍历每个数组元素并为每个数组元素分配空间:
char** chunks = calloc(24, sizeof(char*));
for (i=0; i<24; i++) {
chunks[i] = calloc(24, sizeof(char));
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以在复制之前write和crite之前分配此内存:
void write(char** dest, char* src, int index) {
int i = 0;
dest[index] = calloc(24, sizeof(char));
for (i = 0; src[i] != '\0'; i++) {
dest[index][i] = src[i];
}
dest[index][i] = '\0';
return;
}
void crite(char** dest, char src, int index) {
int i = 0;
dest[index] = calloc(2, sizeof(char));
dest[index][0] = src;
dest[index][1] = '\0';
return;
}
Run Code Online (Sandbox Code Playgroud)