LinuxQuestions.org
Latest LQ Deal: Linux Power User Bundle
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-22-2011, 10:52 PM   #1
kvm1983
Member
 
Registered: Jul 2009
Posts: 47

Rep: Reputation: 1
seg fault: cannot access memory


Hello all,
I am facing a segmentation fault that is caused by the code that looks similar to the one below.

Code:
void main()
{
  int a;
  test (&a) ;
  printf("New value of a: %d", a);
}

void test (int *a)
{
  int b = 10;
  *a = b;
}
I get a seg fault at the statement '*a = b' in the function test(). When I print *a inside the function test using gdb, it complains that it "Cannot access memory at address 0x4e2801d8". This is on a 64 bit machine running OpenSUSE and gcc 4.3.1.

The program runs fine on a 32 bit machine running OpenSUSE and gcc 4.5.0 .

Any help is appreciated,
Kshitij
 
Old 01-22-2011, 11:43 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
What's the width of int on your distro? I'm wondering if it's 32 bits, because without a forward declaration test is implicitly declared with an int argument, which would mean the pointer isn't being passed correctly. Try a forward declaration of test and see if that fixes it.
Kevin Barry

PS Notice how the highest set bit of 0x4e2801d8 is the 30th, which isn't definitive, but it certainly doesn't exclude the problem I suggested.

Last edited by ta0kira; 01-22-2011 at 11:46 PM.
 
1 members found this post helpful.
Old 01-23-2011, 05:10 AM   #3
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946
ta0kira is exactly right. Because test() is implicitly declared, the older GCC uses the int type for all parameters, just like the C standards dictate. x86_64 is an LP64 platform, where long and pointers are 64-bit, but ints are 32-bit. (If you use the -m32 option for GCC, it'll compile normal 32-bit x86 code; on 64-bit distributions the default is -m64 which will compile 64-bit code.)
Thus, the function will receive an invalid pointer to a, unless the address of a has all zeros in the upper 32 bits. You can print the address of a in main (in hexadecimal) with e.g.
Code:
printf("a is at %p\n", (void *)(&a));
and in the test function with e.g.
Code:
printf("a is at %p\n", (void *)a);
if you wish to check this for yourself.

Newer GCC versions seem to promote the pointer parameters to long (which is always sufficiently large integer type to hold the pointer) when using an undeclared function. To reproduce the problem on later GCCs too, you'll need to e.g. rename test to test2 and use an wrapper function to reproduce the previous behaviour:
Code:
void test(int p)
{
    printf("Pointer is %x\n", p);
    test2((int *)p);
}
If you had compiled your test program with warnings enabled, you'd have noticed the
Code:
warning: implicit declaration of function ‘test’
To fix this, either add a proper declaration for the test function, or just define it prior to using it. Order is important in C.

Whenever you have problems with your code, especially segfaults, you should first compile with full warnings (use the -Wall option for GCC), and fix the warnings first. Only in rare cases are the warnings bogus.
Nominal Animal

Last edited by Nominal Animal; 03-21-2011 at 06:00 AM.
 
1 members found this post helpful.
Old 01-23-2011, 09:06 PM   #4
kvm1983
Member
 
Registered: Jul 2009
Posts: 47

Original Poster
Rep: Reputation: 1
Thank you for your replies. The function test was declared before (not shown in the code I had posted), so that was not the problem. The problem was that in the declaration of the function I had

Code:
void test (int a);
instead of
Code:
void test (int *a);
As you said, I figured it out by turning warnings on, one of which said

Code:
Passing argument 1 of test makes integer from pointer without a cast
I dont know why it didnt fail on the other system running gcc 4.5, but this solved it.

Apart from that, I didnt know that implicit declarations of a function can mess up pointers, so thanks a lot for your help.

- Kshitij
 
Old 01-23-2011, 10:54 PM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by kvm1983 View Post
I dont know why it didnt fail on the other system running gcc 4.5, but this solved it.
You also said it was a 32-bit distro, which means a pointer and an int were the same size. That doesn't appear to be the case with your current distro. I doubt it was the difference in compiler version.
Kevin Barry
 
Old 01-24-2011, 01:58 AM   #6
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946
@ta0kira: You're right, it's not the compiler. All GCC versions I have (4.1.3, 4.3.4, 4.4.3) promote pointer types correctly to the long type. That means the culprit was the erroneous function prototype (int parameter instead of a pointer to int).

The erroneous code will only crash on x86_64 if the variable is located above 2^32 -- that is, if the high 32 bits of the address are not zero. On x86, the code will not crash because ints and pointers are the same size.
Nominal Animal

Last edited by Nominal Animal; 03-21-2011 at 07:34 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Terminated pthreads decreasing memory, until Seg Fault truboy Linux - Software 1 01-04-2011 08:17 AM
[SOLVED] Seg Fault. Memory address not being passed to function. prushik Programming 4 04-21-2010 06:39 AM
seg fault when strtok on static memory c++ gearoid_murphy Programming 5 04-30-2007 11:04 AM
seg. fault when allocating memory via a pointer inside a struct elmafiacs Programming 4 02-20-2005 07:26 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:20 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration