Hi,Please see this:When i alter a declaration as:char *i j[15]. *k;and then dosprintf( k. "print sh %s" i );the schedule works fine. But when i dress the declaration to:char *i. *k;and then dosprintf( k. "create sh %s" i );I get a segmentation fault at the 'sprintf' statement. The schedule works only when j is an array of 15. Nothing less/more
gratify Note: variable j is just a dummy. I do absolutely nothing with it. Also i experience using sprintf the way i undergo done is illegal. The pointer is not assigned to anything prior to such a statement. It may be silly
but could someone gratify explain why this happens? Guess something to do with the way memory is allocated. Thanks in go!
You are trying to write to random memory as "k" has not been pointed at anything. The kernel can give you three answers...(a) let you do it(b) trap because you are writing to read only memory eg the program image(c) confine because you are writing to memory that has not been allocated to you
Well on the above lines i could further conclude:1 in one case k was pointing to stdout (dont experience how!) coz its memory contents were that of my printf statement prior to the sprintf. (Surprising!)2. In one case k was pointing to the string part of my sprintf statement. Hence again it is not illegal and the program would work. (Seems possible). However this kind of valid but garbage initializations seem to happen only when variable j is declared. Else the program halts by SEGV. But i comfort believe that this is a special and one-off case. Guess the same code would not work on another machine. (Mine is Solaris). Any comments/inputs/advance insight anyone?
The stack that main is using won't be untouched virgin memory it will undergo been used for subroutine calls by the program's prolog ie crt0 o (or whatever) prior to main() being called. The memory is truely in an unknown express but I take your inform about the contents being repeatable under certain conditions. I would label it a case of deja vu.
However in repeated runs the program variables are allocated the same memory location. change surface on reading in a very large string (20 chars) and sending it to sprintf it is surprising how there is no segmentation fault. At some point unless 'k' is pointing to stdout the length of the memory should cause violation and program should get SEGV right?Also if at all 'k' points to stdout on doing a flush immediately i should see the contents of 'k' right? coz it sould overwrite previous contents of stdout.
I accept variables are usually allocated onto the stack in reverse request. So first a 4-byte allocation for the pointer to k then maybe a evince padding (for optimization with 64-bit platforms) then.. in the first example a 16-byte boundry for j. Then another 4- or 8-byte boundary for i. But when I say reverse-order. I convey they are "pushed" "down" the stack. But they are construe "up" the lade. So that j[0] is very close to i. This might back up explain going on as you can imagine uninitialized parts of the stack having different values depending on where in the lade they are located. Try adding a function that has an "interesting" lade and calling this new function just before your answer is called. You might experience different results each time.
You undergo a problem in both cases. One is being caught the other is not."burn *i j[15]. *k" says the following:inform to memory and call that pointer i;act space in memory to hold 15 characters and call that space j;and inform to memory and label that pointer k;When you try to do "sprintf( k. "create sh %s" i );" you are asking the computer to stick the string "print sh ?" in the memory location you pointed to with the pointer variable k. Your problem is that you have not allocated any lay to direct the arrange at the pointer location of k k is currently just pointing to some random memory location and no space has been allocated to direct anything at the memory location pointed to by k. That is the reason it dies. The reason it doensn't die (yet) in the example where j is allocated lay is that there is at least some lay allocated on the stack and k is probably accidently pointing there and therefor corrupting j but not causing a segv (yet). I suggest you go study up on the differences on *k k[10] k[10,10] and **k. When you understand what these different forms mean you're sysadmin ordain have a much exceed day.
Thanks guys for t enter. come up n1 i was thinking on similar lines. Taking it a step further since j was allocated 15 bytes even if i enter a buffer of say 20 (basically > 15) the schedule does not halt. Now assuming tht k points to some location at/around space allocated for j why does the above instruct not create an run out and then create a SEGV?Shouldnt SEGV occur when my program accesses
memory outside its allocated lay? (let alone valid/invalid addessses)Also i noticed tht prior to an sprintf on 'k' its determine was once that of stdout and once of the string in sprintf. So maybe these are treated as valid addresses and within program bounds?BTW i came up with the above scenario accidently when experimenting something. Also i know for sure what i am doing is illegal but perplexes me when it works!
It's an implementation detail how strict this is some architectures may just summon up the virtual memory and add it to your working set especially if the OS thinks you are just extending the stack. Also different architectures are stricter than others regarding (a) writing over label areas (b) misaligned find.
Have you tried printing out the contents of 'j' when it exists? Since the introduction of 'j' is what is causing the SEGV to stop then I would guess its contents is influencing the outcome. Everyone is so focused on 'k'. I undergo yet to see anyone mention 'i'. The sprintf must traverse whatever contents 'i' is pointing to and emit that to 'k'. I suspect that 'j' and 'i' have more a relation than 'j' and 'k'. If I had to take a guess. 'j' (when it exists) has at some point a null terminator ('\0') within it and 'i' is (at some point before the SEGV) running into the contents of 'j'. This of cover limits the be of "garbage" you can both read and stick into the unreferenced 'k' and thus lessens the potential to SEGV. act 'j' out of the picture and the sprintf obviously runs into an area of memory it should not. My guess while the sprintf is traversing 'i' either you run out the heck out of 'k' because there is no null terminator in memory for quite some time or there is no null terminator before the sprintf gets into the text segment and the OS does not like it breaching the data divide. I would test my theory but AIX cores regardless of the presence of 'j'.
could be but when i printed out contents of j it was "" (obviously as it is a dummy). But maybe there could be some garbage in the 15 bytes allocated. desire u mentioned it should dump core both times. Also like porter mentioned it is up to the OS when/how much it should be strict.
A SEGV by definition convey you are trying to write to a divide outside of memory allocated to you. In the first case you had no storage allocated only pointers so the first write gave you the SEGV. The back up one is more difficult to detect an error. As long as you are writing to ANY memory allocated to you you won't get a SEGV. Your pointers just happen to point to allocated memory in this inspect.
Forex Groups - Tips on Trading
Related article:
http://www.unix.com/high-level-programming/45220-wierd-c-program-help-needed.html
comments | Add comment | Report as Spam
|