0

Imagine I have the following C function :

double * cross_product( double vec1[3], double vec2[3] )
   {
    double *outvec ;

     *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1];
     *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2];
     *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0];
     return outvec ;
 }

why the program return an error in the execution , not in the compilation phase ??

this one also does not work

double * cross_product_2( double vec1[3], double vec2[3] )
   {
    double var ;
    double *outvec = &var;

     *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1];
     *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2];
     *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0];
     return outvec ;
// }
user3466199
  • 21
  • 2
  • 10
  • In your second example, `var` goes out of scope after the end of the function, and the returned address is no longer a valid memory address for you to use. Also note that somewhere, you should `free` the memory. – crashmstr Sep 12 '14 at 19:00

3 Answers3

3

You just created the pointer "outvec", but you dont know where it is pointing. I mean, you didnt alloc the memory where the pointer outvec will write. It is just trying to write data on a random memory space.
You need to "tell" the pointer where it should start writing the data, and reserve that space to you work in.
As Joel said, try doing that by using the code:

double *outvec = malloc(3 * sizeof(double)); 

Sorry about my bad english though... Good Luck!

Quik19
  • 352
  • 3
  • 13
2

You have not initialized your outvec pointer, so you are trying to write data to a null (or garbage) address. Try allocating some memory for it to point at first or declare a static array to return from your function.

e.g.

double *outvec = malloc(3 * sizeof(double));

You get a runtime error because the compiler doesn't evaluate outvec at compile time. So it is not aware of what address you will be trying to access at runtime.

Joel
  • 4,732
  • 9
  • 39
  • 54
  • but must I initialize any pointer before to fill in any other value ?? – user3466199 Sep 12 '14 at 18:14
  • @user3466199 - Yes..In order to use a pointer in some operation, you must make sure that it contains valid address (since the pointers store address ), otherwise you are just performing operations on some random memory location that : 1.May or not be even in your process context. 2.Contains garbage. In this case if you are lucky you get errors, and if not you get expected answers. – Abhishek Choubey Sep 12 '14 at 18:27
  • @user3466199 - In the second code the pointer has a valid memory address, but as far as your implementation is concerned you should store the address of a "double" array inside the outvec pointer. Let me help you with some code... – Abhishek Choubey Sep 12 '14 at 18:40
1

double *outvec contains garbage, since you have not initialised or assigned any value
to it. Any operation on 'outvec' is an operation on garbage, thus the result also contains garbage.

Correction in second code :

     REVISED CODE 
double * cross_product_2( double vec1[3], double vec2[3] )
       {
        double *outvec = NULL; // new change
        outvec = (double *)malloc(sizeof(double)*3); //since you need space for 3 
                                                    //doubles         


     /* 
           *(outvec + i) means, that the calculated value is to be stored at the ith 
             index of the address pointed to by the outvec pointer. That is how arrays
              are indexed using pointers 
     */
         *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1];
         *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2];
         *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0];
         return outvec ;
    // }

Explanation :

You have declared the following variable -
double *outvec;
"outvec" is a pointer that is used to store the address where result will be stored. Being a pointer the variable "outvec" will point to an address where the result will be stored. But since you have not specified what that address that would be, thus "outvec" points
to some random address which is garbage. Thats why we need to specify at what address we want to store the result, and for that
we need to initialise or assign the "outvec" variable with some valid address.

Abhishek Choubey
  • 883
  • 6
  • 16
  • ok , if I add this to lines double ss ; double *outvec = &ss; – user3466199 Sep 12 '14 at 18:19
  • @user3466199 - if the address to which your pointer points to is valid then rest should fall in place unless you make some other mistake. – Abhishek Choubey Sep 12 '14 at 18:36
  • but what the difference to point to an doube and to point to an double array, why I need to declare an array not a simple double, because if I do the same thing on the main program that works perfectely – user3466199 Sep 12 '14 at 18:48
  • when I debug the code it fill the first and the second components normaly, but it crash at the third components !!!!! – user3466199 Sep 12 '14 at 18:53
  • @Blastfurnace - could you reply me about the two previous comments – user3466199 Sep 12 '14 at 19:00
  • [Don't cast malloc in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc), also... 3 bytes? No. – crashmstr Sep 12 '14 at 19:02
  • @user3466199 - If you dont mind - - There are two ways : 1>>>Pass the destination, in which you want to store the result , as an additional parameter to the function, so that when the jobs is done you can return a reference to it to the calling function. 2>>>If you want to store the result in a local variable then explicitly allocate memory to the variable, and when done return the address of that local variable. – Abhishek Choubey Sep 12 '14 at 19:06
  • @Blastfurnace - excuse me my subsequent questions, but I really want to understand that first when I debug the code it fill the first and the second components normaly, but it crash at the third components !!!!!, if I use the proposition of Abhishek the code works also – user3466199 Sep 12 '14 at 19:07
  • @user3466199 - I've corrected all bugs to the best of my knowledge. It should work now. And as mentioned by crashmstr you can ignore the casting part while using malloc. – Abhishek Choubey Sep 12 '14 at 19:12
  • Abhishek- thanks for your help and your time , but if you have more explanation about that I quite happy if you can ... – user3466199 Sep 12 '14 at 19:15
  • @user3466199: Your original code wrote values through an uninitialized pointer which is always an error. You need to have a valid object to hold the results. That could mean adding another function parameter for an output array to store the results. Or you could dynamically allocate memory in the function and then return a pointer to that memory (and you must `free` that memory when you are eventually done with it). – Blastfurnace Sep 12 '14 at 19:16
  • Blastfurnace - can I send you a private msg ? – user3466199 Sep 12 '14 at 19:19
  • @user3466199: Unfortunately, no. Can I suggest, if you are learning `C`, to spend time with a good book? Using `C` requires that you learn memory management and I think a good book may be the best way to learn correct practices. See: [The Definitive C Book Guide and List](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) – Blastfurnace Sep 12 '14 at 19:25
  • @user3466199 - I've added a bit of explanation at the end of my post. Hope it helps. – Abhishek Choubey Sep 12 '14 at 19:28
  • thanks Abhishek another time and also Blastfurnace for the help and the link – user3466199 Sep 12 '14 at 19:37