By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,230 Members | 2,471 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,230 IT Pros & Developers. It's quick & easy.

Again on passing arrays as arguments

P: n/a
Thanks to all of you because I solved the problem related with my
previous post.
I simply made confusion with pointers to pointers and then succeeded
passing the reference to the first element pointer.
:-))
You were right about by mixed code: quickly writing an example to
clarify the matter I made a C++ program, sorry for the inconvenience.

Anyway, although it all works fine with monodimensional arrays,
I still have a problem with irregular matrices (2D arrays with the
first dimension fixed, the second one variable).

I wrote a simple example code which perfectly works in the main
routine, while it arises an access violation if I put it in a
subroutine.
My purpose is to create an irregular matrix like this:

p[0][0] (no element)
p[1][0] p[1][1]

The two code blocks (in "main" and in "test") are identical, just
"p" changes in "*m".
The example is below.

Could you explain me why this occurs ?

Thanx again,
Morgan.
__________________________________________________ _______________
int main(int argc, char *argv[])
{
int **p;

p = (int **)malloc(2*sizeof(int *));
if (p == NULL) {printf("Error: Out of Memory \n"); exit(1);}
p[0] = (int *)malloc(sizeof(int));
if (p[0] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
p[1] = (int *)malloc(2*sizeof(int));
if (p[1] == NULL) {printf("Error: Out of Memory \n"); exit(1);}

p[0][0] = 1; printf("%d\n",p[0][0]);
p[1][0] = 2; printf("%d\n",p[1][0]);
// Next line is normally executed here !!!!!!!!!!!!!!!!!!!
p[1][1] = 3; printf("%d\n",p[1][1]);

free(p);

test(&p);

printf("%d\n",p[0][0]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);

free(p);

system("PAUSE");
return 0;
}

void test(int ***m)
{
*m = (int **)malloc(2*sizeof(int *));
if (*m == NULL) {printf("Error: Out of Memory \n"); exit(1);}
*m[0] = (int *)malloc(sizeof(int));
if (*m[0] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
*m[1] = (int *)malloc(2*sizeof(int));
if (*m[1] == NULL) {printf("Error: Out of Memory \n"); exit(1);}

*m[0][0] = 1;
*m[1][0] = 2;
// Next line causes an access violation here !!!!!!!!!!!!!!!!!!!
*m[1][1] = 3;
// For the exactness it seems to me that the access violation
// arises after the last line, coming back to main... :-( !?
}
____________________________HELP !!!_____________________________
Nov 14 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Sun, 08 Feb 2004 06:29:30 -0800, Morgan wrote:
Thanks to all of you because I solved the problem related with my
previous post.
I simply made confusion with pointers to pointers and then succeeded
passing the reference to the first element pointer.
:-))
You were right about by mixed code: quickly writing an example to
clarify the matter I made a C++ program, sorry for the inconvenience.
If it's a C++ program, why'd you cross-post to comp.lang.c? The code below
looks an awful lot like C, so I'm kind of confused. Also, in acllc-c++, we
ask that you prefix your subject line with either [C] or [C++] so we can
easily tell which language you're using.
Anyway, although it all works fine with monodimensional arrays, I still
have a problem with irregular matrices (2D arrays with the first
dimension fixed, the second one variable).

I wrote a simple example code which perfectly works in the main routine,
while it arises an access violation if I put it in a subroutine. My
purpose is to create an irregular matrix like this:

p[0][0] (no element)
p[1][0] p[1][1]

The two code blocks (in "main" and in "test") are identical, just "p"
changes in "*m".
The example is below.

Could you explain me why this occurs ?

Thanx again,
Morgan.
__________________________________________________ _______________ int
main(int argc, char *argv[])
You're not using argc or argv. If you don't use them, leave them out.
{
int **p;

p = (int **)malloc(2*sizeof(int *));
In C, don't cast the return from malloc; it gains you nothing, and it can
hide bugs (which it did in this case). In C++, use `new' instead. If you
use malloc, you should remember to include <stdlib.h> (or <cstdlib> in C++).
if (p == NULL) {printf("Error: Out of Memory \n"); exit(1);}
You need <stdio.h> (or <cstdio> in C++) for printf. 1 is a non-portable
exit code. The only portable codes are 0 (indicates success),
EXIT_SUCCESS, and EXIT_FAILURE.
p[0] = (int *)malloc(sizeof(int));
if (p[0] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
p[1] = (int *)malloc(2*sizeof(int));
if (p[1] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
Please you more vertical space. It's your friend, really. Until you become
much more familiar with the language, one statement per line is a good
rule of thumb.
p[0][0] = 1; printf("%d\n",p[0][0]);
p[1][0] = 2; printf("%d\n",p[1][0]);
// Next line is normally executed here !!!!!!!!!!!!!!!!!!!
It took me a while to figure out what you meant by that comment. I don't
know if you're a native English speaker or not, but you meant, "Next line
is executed normally here." Inverting the order of those two words changes
the meaning drastically.
p[1][1] = 3; printf("%d\n",p[1][1]);

free(p);
Memory leak: you forgot to free() p[0] and p[1] first.
test(&p);

printf("%d\n",p[0][0]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);

free(p);

system("PAUSE");
return 0;
}

void test(int ***m)
{
*m = (int **)malloc(2*sizeof(int *));
if (*m == NULL) {printf("Error: Out of Memory \n"); exit(1);}
*m[0] = (int *)malloc(sizeof(int));
if (*m[0] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
*m[1] = (int *)malloc(2*sizeof(int));
if (*m[1] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
You've got duplicated code here. Why not call test() twice instead of
having cut-and-pasted code?
*m[0][0] = 1;
*m[1][0] = 2;
// Next line causes an access violation here !!!!!!!!!!!!!!!!!!!
*m[1][1] = 3;
// For the exactness it seems to me that the access violation // arises
after the last line, coming back to main... :-( !?
You've got the order of operator precedence wrong. You meant

(*m)[0][0] = 1;
(*m)[1][0] = 2;
(*m)[1][1] = 3;
}
____________________________HELP !!!_____________________________


Josh
Nov 14 '05 #2

P: n/a

"Morgan" <up*****@tin.it> wrote in message
news:ec*************************@posting.google.co m...
Thanks to all of you because I solved the problem related with my
previous post.
I simply made confusion with pointers to pointers and then succeeded
passing the reference to the first element pointer.
:-))
You were right about by mixed code: quickly writing an example to
clarify the matter I made a C++ program, sorry for the inconvenience.
I am reading this in alt.comp.learn.c-c++ and it looks like you have also
posted this to comp.lang.c.
The people in comp.lang.c won't be happy if your posting C++ code to their
newsgroup.
Anyway, although it all works fine with monodimensional arrays,
I still have a problem with irregular matrices (2D arrays with the
first dimension fixed, the second one variable).

I wrote a simple example code which perfectly works in the main
routine, while it arises an access violation if I put it in a
subroutine.
My purpose is to create an irregular matrix like this:

p[0][0] (no element)
p[1][0] p[1][1]

The two code blocks (in "main" and in "test") are identical, just
"p" changes in "*m".
The example is below.

Could you explain me why this occurs ?

Thanx again,
Morgan.
__________________________________________________ _______________
int main(int argc, char *argv[])
{
int **p;

p = (int **)malloc(2*sizeof(int *));
if (p == NULL) {printf("Error: Out of Memory \n"); exit(1);}
p[0] = (int *)malloc(sizeof(int));
if (p[0] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
p[1] = (int *)malloc(2*sizeof(int));
if (p[1] == NULL) {printf("Error: Out of Memory \n"); exit(1);}

p[0][0] = 1; printf("%d\n",p[0][0]);
p[1][0] = 2; printf("%d\n",p[1][0]);
// Next line is normally executed here !!!!!!!!!!!!!!!!!!!
p[1][1] = 3; printf("%d\n",p[1][1]);

free(p);

test(&p);

printf("%d\n",p[0][0]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);

free(p);

system("PAUSE");
return 0;
}

void test(int ***m)
{
*m = (int **)malloc(2*sizeof(int *));
if (*m == NULL) {printf("Error: Out of Memory \n"); exit(1);}
*m[0] = (int *)malloc(sizeof(int));
if (*m[0] == NULL) {printf("Error: Out of Memory \n"); exit(1);}
*m[1] = (int *)malloc(2*sizeof(int));
if (*m[1] == NULL) {printf("Error: Out of Memory \n"); exit(1);}

*m[0][0] = 1;
*m[1][0] = 2;
// Next line causes an access violation here !!!!!!!!!!!!!!!!!!!
*m[1][1] = 3;
// For the exactness it seems to me that the access violation
// arises after the last line, coming back to main... :-( !?
}
____________________________HELP !!!_____________________________


First decide if your writing C code or C++ code.

If your writing C++ code try something like this:

#include <iostream>

/* function declaration & definition */
void foo(int** p){
std::cout<< "p[0][0] = " << p[0][0] << '\n' ;
std::cout<< "p[1][1] = " << p[1][1] << '\n' ;
p[0][1] = 21;
p[1][0] = 31;
}
/* simply prints two values and alters two */
int main(){
/** establish some values for dimensions **/
unsigned int DIM1 =2;
unsigned int DIM2 =2;

/** create array **/
int** ArrayIdent = new int*[DIM1];
for(unsigned int i=0; i<DIM1; ++i)
ArrayIdent[i] = new int[DIM2];

/** assign some values **/
ArrayIdent[0][0] = 1;
ArrayIdent[0][1] = 2;
ArrayIdent[1][0] = 3;
ArrayIdent[1][1] = 4;

/** pass to function **/
foo(ArrayIdent);

/** print a couple of values **/
std::cout<< "ArrayIdent[0][1] = " << ArrayIdent[0][1] << '\n' ;
std::cout<< "ArrayIdent[1][0] = " << ArrayIdent[1][0] << '\n' ;

/** free memory **/
for(unsigned int i=0; i<DIM1; ++i)
delete [] ArrayIdent[i];
delete [] ArrayIdent;

return 0;
}
I know it's logical to think of an extra level of indirection to pass the
address of a pointer but you don't need it here, simply pass the array
identifier by value(as this is the address* of the array).

*virtual address or whatever type of addressing your system uses. Should be
fine in most cases but I believe there are some systems out there which use
varaible sized pointers and caution should be exercised in this case when
passing any pointer. (i.e passing 32-bit pointers to 64-bit routines and
vice versa).
HTH.

Nov 14 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.