3

Yes, I've read this question & answers: Passing an array by reference in C?. I have a similar problem and implemented the same idea from that question.

However, I still get an error from the following code:

#include <iostream>

void FillArray(int** myArray)
{
   free( *myArray ) ;
   * myArray = (int*) malloc(sizeof(int) * 2);

   *myArray[0] = 1;
   *myArray[1] = 2;
}

int main()
{
   int* myArray = NULL;
   FillArray(& myArray);    
   return 0;
}

I got the following run-time error right after the FillArray function ends:

Unhandled exception at 0x773115de in Program.exe 0xC00000005: Access violation writing location 0xcccccccccc.

I'm using Visual Studio, opened Visual C++ Empty Project. And the file named main.cpp. Does that mean it's compiled with C++ compiler instead of C compiler? If so, how can I open a file which will be compiled only C compiler? I tried renaming main.cpp with main.c, but still have the same problem. (I'm asking this question, because I read some about "pass by reference" and saw that it's different in C and C++.)

Sorry for this very fundamental question.

I will be appreciated for any help,

Sait.

14
  • 1
    There's no such thing as a reference in C... Commented May 3, 2012 at 20:12
  • 2
    "Pass by reference" is just a generic way of referring to it. In C, passing by reference is implemented via pointers. Give the guy a break. Commented May 3, 2012 at 20:14
  • 1
    @EdS.: Passing by reference is language agnostic programming terminology. Or perhaps I should say "computer science". Whether C has C++-like references or not, if somebody asked me if C has pass by reference, I'd answer yes. Commented May 3, 2012 at 20:29
  • 2
    @post_erasmus: Exactly why we should use correct terminology :). In C, you are always passing a copy. If you pass a pointer, a copy of said pointer is made and passed to the function. Now, both pointers point to the same memory location, but the pointers themselves are unique. That is why this will work as intended void foo(struct foo *p) { p->some_member = 1; } but this will not void foo(struct foo *p) { p = malloc(sizeof(struct foo)); }. In the latter case only the copy will be modified. Commented May 3, 2012 at 20:57
  • 1
    calling by reference and calling by value are common idioms in programming. although they are not pure technical terms (eg. some consider java passes objects by reference others say references are passed by value instead), 'passing by reference' does not necessarily mean using 'reference' types in C++. Commented May 3, 2012 at 21:17

3 Answers 3

10

Precedence is not working as you expect it to be. Try these:

(*myArray)[0] = 1;
(*myArray)[1] = 2;

(Note: iostream is not C. It's C++.)

Sign up to request clarification or add additional context in comments.

Comments

2

Your problem is one of operator precedence.

The [] operator binds more tightly than the * operator, so

*myArray[1] 

is the same as

*(myArray[1]).  

This is wrong, as the top level pointer only has enough memory allocated for one pointer. You want:

(*myArray)[1] = 2;

On a side note, there is no good reason to mix C and C++ like you have. Obviously you have C++ code here, so prefer new and delete over malloc and free because the latter two do not take into account constructors and destructors for complex objects.

6 Comments

So the code does have problems, but there's a red herring here -- it's perfectly legal to call free on a NULL pointer. (It, as you may expect, does nothing.)
@shanef22: That's true, I should have clarified.
Yes. It could be, maybe, a bad practice; but as @shanef22 says, it didn't change anything. I still got the same error.
@zagy: I wrote my answer too quickly, sorry about that. It was actually a bit more subtle, see my updated response.
@EdS.: Sorry, I implemented junjanes answer first. :) Thanks for your answer and helping about the terminology as well ...
|
1

Good:

int main()
{
   int* myArray = NULL;
   FillArray(& myArray);   
   ...

Good:

void FillArray(int** myArray)
{
   * myArray = (int*) malloc(sizeof(int) * 2);

Catastrophically bad:

void FillArray(int** myArray)
{
   free( *myArray ) ;
   * myArray = (int*) malloc(sizeof(int) * 2);
   ...

Better:

void FillArray (int** myArray)
{
   if (myArray)
     free (*myArray);
   *myArray = (int*) malloc(sizeof(int) * 2);
   ...

ALSO:

   *(myArray[0]) = 1;
   *(myArray[1]) = 2;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.