I am a C beginner, and I am curious why this gives me a Seg Fault everytime:
#include <stdio.h>
#include <stdlib.h>
struct Wrapper {
int value;
};
int main () {
struct Wrapper *test;
test->value = 5;
return 0;
}
I know I don't fully understand pointers yet, but I thought that
struct_ptr->field
is the same as
(*struct_ptr).field
so trying to make an assignment right to the field should be ok. This works like expected:
struct Wrapper test;
test.value = 5;
but I am curious why using the pointer causes a Seg Fault.
I am on Ubuntu 9.04 (i486-linux-gnu), gcc version 4.4.1
You didn't assign the pointer to anything. It's an uninitialized pointer pointing to who knows what, so the results are undefined.
You could assign the pointer to a dynamically created instance, like this:
int main () {
struct Wrapper *test;
test = (struct Wrapper *) malloc(sizeof(struct Wrapper));
test->value = 5;
free(test);
return 0;
}
EDIT: Realized this was C, not C++. Fixed code example accordingly.
You need to create an instance of Wrapper first:
struct Wrapper *test;
test = new struct Wrapper;
test->Value = 5;
Good luck.
You are using an uninitialised pointer, hence the segfault.
Catching this kind of error is possible, if you turn on some more warnings, using -Wall for example
You need to use -Wall in conjonction with some optimisation (-On) for the warning to appear. For instance, compiling your code with
gcc -Wall -O2 -c test.c
resulted in the following error message :
test.c: Dans la fonction «main» :
test.c:10: attention : «test» is used uninitialized in this function
While using french word, this compiler message is not an insult but a warning ;)
See below for a code allocating memory for your test pointer
int main () {
struct Wrapper *test;
test = malloc(sizeof(struct Wrapper))
if(test == NULL) {
/* error handling */
}
test->value = 5;
free(test)
return 0;
}
Related
I was wondering how to solve a Core dumped issue on my C code.
When I compile it with: g++ -g MatSim.cpp -o MatSim -lstdc++ -O3, I get three warnings, this is one (The other two are similar and are only differentiated by the string variable name):
MatSim.cpp: In function ‘int main()’:
MatSim.cpp:200037:27: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
fscanf(TM,"%255s",string2);
The principal aspects of my code and the related part that the compiler reports:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
int to_int(char string[256])
{
if( strcmp(string,"0") == 0 )
{
return 0;
}
...
else if( strcmp(string,"50000") == 0 )
{
return 50000;
}
return -1;
}
int main()
{
int a,b,div,value,k,i,j,tm,ler;
char string[256];
char string1[256];
char string2[256];
FILE *TM;
TM = fopen("TM","r");
if( (TM = fopen("TM","r")) == NULL)
{
printf("Can't open %s\n","TM");
exit(1);
}
fscanf(TM,"%255s",string2);
tm = to_int(string2);
fclose(TM);
...
}
I have tried the reported suggestion in here and I tried to understand what was posted in here. But, I don't see its application on my code.
Finally, when I run the exe file, it returns:
Segmentation fault (core dumped)`.
In your code, you're fopen()ing the file twice. Just get rid of the
TM = fopen("TM","r");
before the if statement.
That said, you should check the value of fscanf() to ensure success. Otherwise, you'll end up reading an uninitialized array string2, which is not null-terminated which in turn invokes undefined behaviour.
Please be aware, almost all string related functions expect a null-terminated char array. If your array is not null terminated, there will be UB. Also, it is a good practice to initialize your automatic local variables to avoid possible UB in later part of code.
You are opening the file twice.
Alll you need is this:
FILE *TM = fopen("TM","r");
if (TM == NULL) { /* file was not opened */ }
I want gcc to optimize away unused function pointers. Ie remove the code completely from the final executable. So far I was not able to achieve this.
Here is updated code:
#include <stdio.h>
struct inner {
void (*fun)(void);
void (*fun2)(void);
};
struct inner2 {
void (*fun)(void);
};
struct foo {
struct inner in;
struct inner2 in2;
};
void lessfun(){
printf("lessfun\n");
}
void morefun(){
printf("morefun\n");
}
const struct foo inst = {
{ .fun = lessfun, .fun2 = morefun },
{ .fun = lessfun }
};
void test(struct foo *f){
f->in.fun();
}
int main(int argc, char *argv){
struct inner2 in = inst.in2;
inst.in.fun();
inst.in.fun2();
in.fun();
/////////////// alt1: nm out | grep morefun -> found
test(&inst);
///////////////
/////////////// alt2: nm out | grep morefun -> not found
struct inner in;
struct inner in2 = inst.in;
in = in2;
test(&in);
///////////////
}
compiler flags: -Os -fdata-sections -Wl,--relax,--gc-sections -ffunction-sections
link flags: -flto -Os -fdata-sections -Wl,--relax,--gc-sections
Compiler: arm-none-eabi-gcc
Here the compiler will include both method1 and method2 into the final program even if they are never used. It is the assignment that seems to make this happen. But if they are never called, it would be nice to completely remove the code to method1 and method2. This obviously happens because technically the function is in fact referenced in the assignment, but since the variable in the assignment is never user it should still be possible to determine that the method is never called.
Do I need to declare it const somehow? How?
How can I have gcc remove the unused functions?
EDIT: I was able to sort of make it work as you see above. But it only works if I do not make a copy of any members of the struct. If a direct copy is made and passed to a function, the compiler fails to optimize unused functions. I'm now 60% certain that this is some kind of optimizer bug.
EDIT2: you may not even reproduce the bug. But here is the scenario that creates it.
struct mydev dev;
struct dev_spi spi;
struct dev_spi sp2 = board.spi0;
sp2.writereadbyte(0);
spi = sp2;
//test(&cpu.spi0);
// using only this call results in correct optimization
// many unused methods pointed to by members of "board" var are gone.
mydev_init(&dev, &spi);
// using this version breaks optimization
// all methods referenced by "board" struct are included in final program
mydev_init(&dev, &sp2);
// this one breaks optimization as well
// same as above.
mydev_init(&dev, &board.spi0);
// there is no difference other than one passes variable directly to the init function
// and the other uses a temp variable.
I was compiling this program and the compilation went fine. The moment I executed it, it failed with free(): invalid pointer error.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *p = NULL;
if ((p = (char *) malloc((int)sizeof(char) * 100)) == NULL) {
printf("ERROR: unable to allocate memory\n");
return -1;
}
p += 50;
free(p);
return 0;
}
I compiled using gcc -o memtest m.c command.
Are there any GCC compiler options that will give a warning/error/indication about these invalid pointer errors during compile time?
No. Use Electric Fence or Valgrind.
compile time no, runtime - yes: http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging
The closest you may get for compile time is: http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html
No, such errors aren't detected at compile-time because in practice such detection would only trigger for the most trivial cases, like your example.
I would like to see a small but complete snippet of code that will cause Clang's static analyser to complain. My motivation is mostly that I'm trying to get it to work on my PIC32 code, and I need a way to distinguish between "all the code is fine" and "it's not actually doing anything". It's also partly curiosity, since I can't seem to come up with a simple example myself.
C89/ANSI or C99 is fine, and ideally I'd like to see it pick up a simple memory leak. My usage is
clang --analyze test.c
I found a "bug" in my code (the only one ;-) that triggers by that, and that is not detected by -Wall. I cooked it down to the following
struct elem {
struct elem *prev;
struct elem *next;
};
#define ELEM_INITIALIZER(NAME) { .prev = &(NAME), .next = &(NAME), }
struct head {
struct elem header;
};
#define HEAD_INITIALIZER(NAME) { .header = ELEM_INITIALIZER(NAME.header) }
int main(int argc, char ** argv) {
struct head myhead = HEAD_INITIALIZER(myhead);
}
This is a relatively straight forward implementation of a linked list, but this is not important here. The variable myhead is unused in a common sense application of the term, but for the compiler it is used since inside the initializer the address of a field is taken.
clang correctly analyzes this as
/tmp 11:58 <722>% clang --analyze test-clang.c
test-clang.c:25:15: warning: Value stored to 'myhead' during its initialization is never read
struct head myhead = HEAD_INITIALIZER(myhead);
^ ~~~~~~~~~~~~~~~~~~~~~~~~
1 diagnostic generated.
Edit: I found another one that also detects stack memory proliferation
char const* myBuggyFunction(void) {
return (char[len + 1]){ 0 };
}
This is not detected by gcc, open64 or clang with -Wall, but by clang with --analyze.
I have a function in which one of the function arguments is an integer. During function invocation I am passing an enumerated datatype to this function. After building using gcc, any access to the INTEGER variable inside the function causes a segmentation fault.
Sample code:
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
}
}
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
int main (int argc, char *argv [])
{
somefun (STATE_NICE);
}
First off, The enum is defined in main() and does not exist for somefun(). You should define the enum outside of main, although I cannot see how this is causing a crash.
After defining the enum outside of the main you should define somefun to be somefun( E_STATE nState ) and test again.
I compiled and ran that code exactly (cut & paste) on my computer, using gcc version 4.2.4, with no errors or segmentation fault. I believe the problem might be somewhere else.
Actually runs for me:
bash $ cat bar.c
#include <stdio.h>
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
default:
printf("Hello?\n");
}
}
int main (int argc, char *argv [])
{
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
somefun (STATE_NICE);
return 0;
}
bash $ gcc -Wall bar.c -o bar
bar.c: In function 'main':
bar.c:22: warning: unused variable 'E_STATE'
bash $ ./bar
Hello?
bash $
Made a couple of changes, but it ran without them. (1) added a tag in the switch just so it had something; (2) added the #include <stdio.h> and printf so I could tell that it had run; (3) added the return 0; to eliminate an uninteresting warning.
It did run successfully with none of the changes, it just didn't do anything visible.
So, what's the OS, what's the hardware architecture?
Update
The code changed while I was trying it, so here's a test of the updated version:
bash $ cat bar-prime.c
#include <stdio.h>
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
default:
printf("Hello?\n");
}
}
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
int main (int argc, char *argv [])
{
somefun (STATE_NICE);
return 0;
}
bash $ gcc -Wall bar-prime.c -o bar-prime && ./bar-prime
Hello?
bash $
Still works. Are you getting a core file in your version? Have you tried getting a stack trace?
Your situation is like specific to sun sparc hardware or similar. Please post uname -a and output of dmesg
From all your answers it seems that the code is logically correct, and I need to investigate the real reason for the crash. I will investigate it and post it soon.