C program, pointer argument won't hold values

2020-07-30 03:01发布

问题:

Hi guys I'm sorry to bother you with this but I'm starting to loose it here.. I have recently started programming in C again and I have run into some kind bug that just I can't figure out.. My C program is(should be) an easy one, so it needs to do the following: An undefined number of natural elements is read form the keyboard until a 0 is read. After that it has to compute the product of all elements and compute the number of 0-s on the end of that result..

int input(int* v)                      {

    int n = 0;   
    do                                                            
    {
        n = n + 1;
        v = (int*) realloc(v,n*sizeof(int));        printf("Enter number %d: ",n);          scanf("%d",&v[n-1]);
    }
    while(v[n-1] != 0);           
    n--;
    return n;  }

int tZeros(int* v, int eNb)     {    
    int i;
    int  val = 1;
    for(i = 0; i < eNb; i++)
    {
        val = val * v[i];        
    }

    i=0;
    while(val % 10 == 0)
    {
        i++;
    }  
    return i; }

int main (int argc, char** argv)     {

    int* v = NULL;                                                  
    int eNb = input(&(*v));                                          
    if(eNb>0)                                                       
    {
        int zeros = tZeros(v, eNb);
        printf("The number of ending zeros in the product of the given numbers is: %d",zeros);

    }
    else
    {
        printf("No elements to do computations with!\n");
    }
    free(v);
    return 0; 
    }

The input function should return two things: The number of elements and the actual elements in the dynamic array.. But after the input function runs the values entered there are all lost.. I pass the argument into input as a pointer so it should change the values at the correct addresses right?

All suggestions are welcome! Thnx!

P.s. I think the problem is with my array v.. after exiting the input function it looses all values..

回答1:

Everything in C is passed by value, so when you perform the assignment:

v = (int*) realloc(v,n*sizeof(int));

You are assigning a new value to the local copy of the variable v. If you want to change the value of the pointer itself (as opposed to modifying what the pointer already points to) you will need to pass a pointer to a pointer and dereference it once to perform the assignment, i.e.,

int ModifyPointer( int **v )
{
    // error checking and whatnot
    *v = realloc(*v,n*sizeof(int));
}

Think of it this way; you have a pointer p that resides at memory address 0xA and points to memory address 0xFF. You pass p to a function and a copy v is created. The copy v resides at memory address 0x2A, but still points to memory address 0xFF.

                     p(0xA)      v(0x2A)
                       |            |
                        \          /
                         \        /
                          \      /
                            0xFF

So, when you dereference either pointer you end up referring to the same chunk of memory, but the pointers themselves live in different places in memory. Thus, when you modify the value of the copy it is not reflected in the original (i.e., realloc is creating a new pointer in a new memory location and assigning it to the variable v, but p remains unchanged.)