#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    20
    Rep Power
    0

    Angry Seg fault! Dammit!!


    Hello all. I can't seem to figure out my issue with this funtion. I receive a seg fault when placing a value using a pointer. I will not right out the whole function just the section that matters. With that in mind you will not see a return value.

    Code:
    int *retArrOfNum(int number){
        int *ptrToArr, index = 0, resultdiv, helpnum = 1000000000;
        while(helpnum != 0){
            resultdiv = number / helpnum;
            if(resultdiv == 0){
                helpnum /= 10;
            } else {
                *(ptrToArr + index) = resultdiv;  // SEG FAULT HERE
                number %= helpnum;
                index++;
                helpnum /= 10;
            }
        }
    }
    However when writing this

    Code:
    #include<stdio.h>
    
    int main(){
        int *ptrToTest, index;
        for(index = 0; index < 10; index++){
            *(ptrToTest + index) = index + 1;
        }
        for(index = 0; index < 10; index++){
            printf("Here is the integer at position %d: %d\n", index, *(ptrToTest + index));
        }
        return 0;
    }
    It seems to work like a charm. Figured I needed a new set of eyes on this because at this point I am stumped. Thank you!!
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    You never told ptrtoArr where to point to. You're trying to dereference an uninitialized pointer, the programming equivalent to Russian Roulette.

    Solution: initialize the pointer! If you need to create a new array, then use malloc; be sure to call free to deallocate it when you're finished with it (not really necessary in this program, but a valuable discipline to develop to avoid memory leaks in the future).

    As for the same thing not happened in main, that just blind stupid luck -- bad luck, because you were fooled into thinking that it works that way. An local uninitialized pointer, like all uninitialized local variables, contains garbage, which is whatever was last left in those memory locations. A garbage pointer could point anywhere, most likely to a memory location outside your program's memory space, resulting in a segfault. If it just happens to access a location within your program's memory space, then it overwrite (AKA "clobber") whatever useful-until-now part of your program that receives that dubious honor (kind of like a random sniper victim). It could be your program code, the stack, variables, whatever. The resultant corruption may cause symptoms that even you would notice, or it may just silently mess things up. Like if you were writing files of data to disk, that data could be corrupted and you wouldn't notice it until much later -- or your customer will be the one to notice it -- and you wouldn't have a clue what had caused it.

    Never use an uninitialized variable! Especially not a pointer!
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    222
    Rep Power
    236
    Here's a thought for ya: Maybe the section which you think matters actually is not or rather the section you think is irrelevant, actually is.

    In the two sections you have provided you define some pointer and later try to access some position in memory with an offset (index in your case), there are a number of possiblities:

    1. you forgot to initialize the pointe rto point to an array you've defined or dynamically allocated.
    2. you are trying to access an ellement outside of the defined array limits, but because you have not provided it's definition , one could not tell the size of this array.

    .....
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    20
    Rep Power
    0
    Originally Posted by dwise1_aol
    You never told ptrtoArr where to point to. You're trying to dereference an uninitialized pointer, the programming equivalent to Russian Roulette.

    Solution: initialize the pointer! If you need to create a new array, then use malloc; be sure to call free to deallocate it when you're finished with it (not really necessary in this program, but a valuable discipline to develop to avoid memory leaks in the future).

    As for the same thing not happened in main, that just blind stupid luck -- bad luck, because you were fooled into thinking that it works that way. An local uninitialized pointer, like all uninitialized local variables, contains garbage, which is whatever was last left in those memory locations. A garbage pointer could point anywhere, most likely to a memory location outside your program's memory space, resulting in a segfault. If it just happens to access a location within your program's memory space, then it overwrite (AKA "clobber") whatever useful-until-now part of your program that receives that dubious honor (kind of like a random sniper victim). It could be your program code, the stack, variables, whatever. The resultant corruption may cause symptoms that even you would notice, or it may just silently mess things up. Like if you were writing files of data to disk, that data could be corrupted and you wouldn't notice it until much later -- or your customer will be the one to notice it -- and you wouldn't have a clue what had caused it.

    Never use an uninitialized variable! Especially not a pointer!
    Thank you very much but that leads me to another question. If I allocate memory using malloc (inside a function)and I return the pointer to that memory.... After leaving the function is that memory still available throughout the rest of my program or is it only available while the function is running.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    8
    Rep Power
    0
    Originally Posted by arbitraryproc
    If I allocate memory using malloc (inside a function)and I return the pointer to that memory.... After leaving the function is that memory still available throughout the rest of my program or is it only available while the function is running.
    If u allocate memory using malloc or any dynamic memory allocation function the memory is allocated on the Heap Area and is available till the program returns an exit status to the OS or(C start up Routine).

    Use Calloc instead of Malloc, as it clears all the bytes to 0's before returning you the address of the dynamically allocated memory! You can be sure of not using or dereferencing Junk locations and avoid Segmentation Faults!!

    The memory can still be accessed through a pointer(Correct Initialized Pointer) from another function.


    P.S : i personally do not suggest you to do it as in a project with lots of modules it becomes mess to debug leaks!!
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Local variables disappear when you leave a function because they reside on the stack. When you call a function, you create a block of memory for that function to use and push it onto the stack on top of all previous memory blocks for all the other functions that have not yet been exited. When you exit a function, it stores its return value in its memory block, uses the return address stored in its memory block to return to where it was called from. the calling function then retrieves the return value and eliminates the memory block by popping it off the stack. In reality, the memory is still there and what was stored in it is still there. It's just that it's no longer at the top of the stack, which is the memory block currently in use. Then the next function to be called will reuse that old memory block and the previous function's data will become the next function's garbage.

    So the behavior of local variables depends entirely on the stack and how it works.

    When you malloc or calloc, memory is allocated from the heap, a special segment of memory that the OS allocates for the program when it executes. That allocation has nothing to do with the stack. Once you allocate memory from the heap, it remains allocated until you explicitly free it with the free() function. Failure to free malloc'd memory when you're done with it is the primary cause of memory leaks, in which you repeatedly malloc memory and don't free it, eventually causing the heap to get all used up and the next malloc fails, causing the program to crash, usually in the middle of the night "for no reason" while performing some vital function like running the state's power grid or keeping somebody alive in a hospital. That is why developing the discipline to prevent memory leaks can be so important.

    Another cause of memory leaks is dropping pointers, which of course will keep you from being able to free that memory. When you malloc or calloc, the return value is the address of the memory that has just been allocated and which you store in a pointer variable. You will need that address to be able to free that memory later on, so you need to keep it and to protect it. If you do not, then you will have dropped that pointer and created a memory leak.

    So to answer your question, the memory you malloc will continue to exist even after you exit the function -- though, of course, when you terminate your program it will cease to exist. But the pointer pointing to that memory could cease to exist when you exit the function! So if you want to continue to make use of that memory outside the function where you malloc it, you need to somehow return its address. Or, if you don't want to use it outside the function, then you need to free it before exiting the function.

    So in summary:
    You either want to only use the malloc'd memory within the function or you want it to continue to exist outside the function.

    If you only want to use it within the function, then free it before you exit.

    If you want it to continue to exist outside the function, then pass its address out of the function in one of a number of ways:

    1. return it as the function's return value and have the calling function assign that return value to a pointer.

    2. In the parameter list, have a parameter that is a pointer to a pointer to that type; eg, if you want to return an int* pointer, you need to use an int** , so that the int* pointer variable whose own address is passed in can be modified to contain the new address. Of course, you will need to pass the address of the pointer variable to the function. If you do not understand this, then please review passing arguments that enable the passed argument to be modified -- you do that by passing the address of the variable to be modified; pointer variables are no different.

    3. Use a global pointer variable. Using global variables is generally frowned upon and discouraged in school, so you should make yourself thoroughly familiar with the previous two approaches.

    I hope that answered your question.

IMN logo majestic logo threadwatch logo seochat tools logo