Segmentation fault

AA All,

I have a code that does this:

char * abc; int a=10,b=20,c=30; abc = (char*) a*b*c; // actually this formula is bit complex than that..but it will do for the example; return strlen(abc);

Now, sometimes I get SEG fault, that's because memory pointed to by abc is not always valid, but most of the time it is. What i want to do is to check whether abc is pointing valid memory or not (just to avaoid exception of SIGSEGV). Check of NULL does not work, as abc points to something, but is it meaningful to me or is it within my segment?? How to check whether a pointer is a valid one?

i am using GCC for x86...

thanks, mudassir.

Reply to
mudassir
Loading thread data ...

This code is abominable. If you're writing code like this, you deserve all the SEG faults you get...

--
Mark McDougall, Engineer
Virtual Logic Pty Ltd, 
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266
Reply to
Mark McDougall

Classic beginner mistake, and posted in the wrong group. Embedded systems won't give you a segmentation fault.

You haven't initialized the pointer, and casting an integer won't get you a string. Get a book on C, read it, then ask further questions in comp.lang.c instead of here.

Clifford Heath.

Reply to
Clifford Heath

Why not? An embedded system can run on an ARM or the like, with memory access exceptions, or on a PC, just as much as a PIC.

Reply to
Paul Burke

The vast majority of embedded systems (by type and by absolute number) have no segmentation hardware. The OP was clearly not using any kind of embedded system (even though some might have such hardware), so he needed to be told that this was not the group for him. Unless you want to assume the mantle of "beginner-C-question-answerer" for this group?

Reply to
Clifford Heath

Days have long gone when embedded systems used to run in a single space and there were no SIGSEGVs. Pointers don't need initialization if the next statement is of their assignment. And who on earth says, integers can't be assigned to char pointers. How much is your experience with C? ten days? Please don't poke your nose into matters you have no idea of. This question is only for pointer geeks...

Oh, come on guys. Don't hate me for this code, I had write it. Just give me a solution if you can come up with any. Anyone heard of catching EFAULT? will it help?

regards, mudassir shabbir.

Reply to
mudassir

if(pointer_is_valid(abc)) return strlen(abc); else return ERR;

It takes application specific knowledge to implement pointer_is_valid().

Reply to
s0lstice

As a pointer expert the best advice I can give is to delete the code you wrote and never write anything like that again. If you explain what you're trying to achieve then we could point you in the right direction.

Wilco

Reply to
Wilco Dijkstra

... snip ...

That (integer to pointer) depends on your system. There are no guarantees. Read the standard.

--
 Chuck F (cbfalconer at maineline dot net)
   
   Try the download section.
Reply to
CBFalconer

Wow all ...

The flamming sounds a little quick and unfair to come to me. (BTW, should I have top-posted or am I in the right here? :p ) When I look at this code, it really looks like a simple example to ask a generic question. Variables abc, a, b, c.. values 10, 20, 30. I guess the OP just doesn't want to disclose its code to ask his question and wrote a dummy code that looks alike his situation.

Besides, I might miss something here, but I don't see the BIG pointer error in the code sniplet. He is not using an integer type as a pointer, but casting an integer value in a pointer type variable, which sounds perfectly correct, C-wise and regardless of the architecture (worse case, the int overflows the pointer, but I have yet to see an architecture like that) However, when someone plays with advanced pointer stuff, he is expected to do it on purpose and fully aware of what he does. Getting a segfault should be investigated and fixed, not prevented by a safety test.

If you get a segmentation fault, it comes from your C library, so I suggest you have a look at its documentation to find how to catch the exception, if it is possible. If you want to avoid the exception to get raised, you have to make a check on your pointer before you use it. I can imagine two cases here:

- There is a multitask OS under your program, that manages an MMU / MPU. Then check your OS documentation, maybe there are APIs to validate your pointer... or maybe not.

- There is only the bare hardware under you program, then I expect you can find your target memory map and can deduce with range tests if your pointer is valid. The segfault is most likely a libc translation of "data abort" (ARM-wise, but other architectures will have equivalent features) exception, which is raised when an invalid address is reached.

Cheers,

St=E9phane

Reply to
Stephane

-------------- from the "-- " marker on is a sig -----------

Why did you fail to snip the sig. portion (above) of my message?

... snip ...

See especially paragraph 6 of the following extract from the C standard (draft N869.txt):

6.3.2.3 Pointers [#1] A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer. [#2] For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal. [#3] An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.48) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. [#4] Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal. [#5] An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be properly aligned, and might not point to an entity of the referenced type.49) [#6] Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
--
 Chuck F (cbfalconer at maineline dot net)
   
   Try the download section.
Reply to
CBFalconer

Depends. Do you want to be able to get the original integer value back later? Don't count on it! There is no guarantee in C that a char pointer (or any kind of pointer) is big enough to hold an int, or vice versa. For that matter, there is no guarantee that different pointer types are the same size, though it is guaranteed that a void pointer can hold any other kind of pointer.

If you want to write portable code with a field that can hold a pointer or an int, you need to use a union.

Seems like you should be asked the same question.

Eric

Reply to
Eric Smith

The flaming sounded a bit tame to me, especially after after insulting Clifford Heath like that. The original code reads exactly as though the OP thought that a "char *" is the C equivalent of a high-level string, and that casting an integer value to a "char *" would make abc a string representation of that value. If that was his thought, then a "beginners guide to C" book would be the best solution. If not, then he should let us know what he is *actually* trying to do - then maybe we can help.

It's either too simplified, so that no one knows what he means, or it is complete rubbish and should be redone from scratch (after reading about the basics of C).

That's a perfectly reasonable attitude - lots of code posted here is test cases and examples, rather than real code. But it still has to make sense.

I have seen architectures where such a cast is invalid (if he is getting segmentation faults, the cast is clearly invalid!). But that's not the point - compatibility of pointer and integer sizes is a minor issue. There is no such thing, in any useful program, as a floating pointer - you must always point *at* *something*. Turning an arbitrary integer into a pointer gives you a pointer to garbage - it cannot possibly be of any use. If the OP's program actually tries to calculate something useful (such as an entry in a complex data structure), then he has to give us the real code if anyone is to help him, as the problem is in that code. Identifying segmentation faults in advance here will only turn his program from one that crashes to one that produces garbage.

Correct.

Drivel. The segmentation fault comes from the processor blocking particularly bad memory access errors - libraries are irrelevant here. And your idea of "catch the exception" sounds very much like you are thinking of C++ - a very different language from C.

Again, you are thinking C++.

No library function will tell you if your pointer is rubbish. At best, you'll be able to find out if using it will crash your program immediately (due to a segmentation fault), or if it will crash your program later (due to corrupting your own program's memory, which the cpu/OS will allow).

I know you are trying to help, but the OP has to give a lot more useful information before anyone can be of any real help here.

Reply to
David Brown

How about I start with when I ported the Ritchie C compiler in 1979? Is almost 30 years enough experience for you? You won't get useful answers until you start asking sensible questions without offending those who attempt to help.

Reply to
Clifford Heath

You don't. You make sure you don't *construct* invalid pointers in the first place.

Once you did construct an invalid one, there's no portable, reliable, or otherwise recommendable test to differentiate it from a valid pointer.

Reply to
Hans-Bernhard Bröker

... but even that won't make the OP's code valid. Accessing any other element of a union than the one last written to causes undefined behaviour just as rigorously as accessing data through a pointer constructed by casting some random integer value does.

Reply to
Hans-Bernhard Bröker

Looking at your code, I would guess your experience is closer to 2 days...

Regards,

--
Mark McDougall, Engineer
Virtual Logic Pty Ltd, 
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266
Reply to
Mark McDougall

Remember this is embedded. C is a glorified assembler. And all that.

I can without problems imagine a situation where the code given makes sense: Suppose you have a processor where at addres 0 you store in 10 languages, 20 strings of at most 30 characters. Now you want a pointer past that area.

A c-compiler can make this system-dependant code defined and working.

So diatribes are a bit of the mark.

Where it starts getting strange is merely where one wants to do run-time checks, insteads of checking the compiler and the actual board it is running on. The most realistic solution is #define's related to the boards memory and such.

Groetjes Albert

--

--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- like all pyramid schemes -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
Reply to
Albert van der Horst

I know this is an embedded group (though the OP might not realise that). C is *not* a glorified assembler - embedded programmers use assembly when they want an assembler. C is a programming language that is significantly higher level than assembly, and its model of the system is higher level than you have in assembly. Thus an integer and a pointer may be almost the same thing in assembly - they are very different in C.

And no matter what language you are using, and what the language and/or hardware physically allows, programs that don't make sense are bad programs.

I'm afraid I don't follow you. It sounds like you have an array of 200 strings of length 30 characters (perhaps 31, with a terminated null). If you want to set a pointer to one of these strings, then that's fine. It does not make sense to point "past that area", except to point just after the end of the array - anything else is undefined according to the C language, and meaningless to the programmer.

No, converting arbitrary integers to pointers is not defined, and it won't work.

The only case I can think of where you'd want to generate arbitrary pointers that are not pointing specifically *at* something, is for some sort of introspection - memory tests, software upgrades, debugging aids, garbage collectors, etc. In those cases, then you would want to use some sort of board-specific limits (like your #defines mentioned below) to avoid crashes. But that does not seem to be the case in the OP's code.

mvh.,

David

Reply to
David Brown

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.