allocating mem in a function and assigning a ptr to the first byte of that mem array...

M

mast2as

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

But i don't it crashes.

Please help,

cheers -mark

#include <stdlib.h>
#include <stdio.h>
#include <cmath>

//#include <map>
#include <string>

void Test( void *add, char st[2] )
{
char *tt = new char[3];
strcpy( tt, st );
add = (void*)tt;
printf( ">> %s\n", (char*)add );
//free( tt );
}

int main( int argc, char **argv )
{
void *a;
Test( a, "ab" );
// crashes here ?
printf( "<< %c\n", *((char*)a + 1 ) );

char *ttt = new char[3];
strcpy( ttt, "ab" );
a = (void*)ttt;
printf( "<< %c\n", *((char*)a + 1 ) );

return 0;
}
 
I

Ian Collins

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

But i don't it crashes.

Please help,

cheers -mark

#include <stdlib.h>
#include <stdio.h>
#include <cmath>

//#include <map>
#include <string>

void Test( void *add, char st[2] )
{
char *tt = new char[3];

You are posting C++ to comp.lang.c. Don't do that!

If we pretend this is C, your problem is the perennial bug of assigning
a value to a local variable (add) and attempting to access it outside
the function.

If you want to allocate memory in a function, pass a pointer to the
pointer you want to use

void test( void **add char st[2] )
{
*add = malloc(3);
 
M

mast2as

You are posting C++ to comp.lang.c. Don't do that!

If we pretend this is C, your problem is the perennial bug of assigning
a value to a local variable (add) and attempting to access it outside
the function.

If you want to allocate memory in a function, pass a pointer to the
pointer you want to use

void test( void **add char st[2] )
{
*add = malloc(3);

Thanks Ian. Yes I mixed C++ and C and was aware it was a perennial
bug, the thing is that i need to go back to some old C code and i am
just not used to it anymore... really sorry, thanks again for putting
me back on the right track - i just started at some code today for so
long, i got lost...
 
N

Nelu

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

But i don't it crashes.

Please help,

cheers -mark

#include <stdlib.h>
#include <stdio.h>
#include <cmath>
//#include <map>
#include <string>

Not standard C headers. Probably C++.
void Test( void *add, char st[2] )
{
char *tt = new char[3];

new operator does not exist in C.
You need to check the value of tt to make sure it's not NULL.
(In your case you should probably catch the exception which is OT
here).
strcpy( tt, st );
add = (void*)tt;

add has the value passed to the function. Here you change the
value that add holds but not the value that was passed to the
function.
printf( ">> %s\n", (char*)add );
//free( tt );

If you'll free tt here, add will point to memory that doesn't
belong to it. Also, be consistent, use new with delete and malloc
with free. Given the fact that this is c.l.c you can only use
malloc with free.
}

int main( int argc, char **argv )
{
void *a;
Test( a, "ab" );

a is an uninitialized pointer. You should not use it like that
because it's value is passed to Test but you are not allowed to
use its value. Remember the observations for add from above? That
function didn't change the value it received because it can't, so
add has the same value as before passing it to Test.
// crashes here ?

Probably. You should pass a pointer to your pointer and change
that value:
void Test( void **add, char st[2] )
and use *a=tt;
Pass *a as Test(&a,"ab") and you should set a to NULL before
calling Test.
printf( "<< %c\n", *((char*)a + 1 ) );

char *ttt = new char[3];
strcpy( ttt, "ab" );
a = (void*)ttt;
printf( "<< %c\n", *((char*)a + 1 ) );

return 0;
}

You'll have to decide what language you want to use. You mix C
and C++ too much. Although the C functions exist in C++ you
should probably use what C++ provides if you want to stay with
C++ (and start posting to the appropriate group, probably
c.l.c++), or use only C code and get help here.
 
N

Nelu

Nelu said:
(e-mail address removed) wrote:
void *a;
Test( a, "ab" );

a is an uninitialized pointer. You should not use it like that
because it's value is passed to Test but you are not allowed to
use its value. Remember the observations for add from above? That
function didn't change the value it received because it can't, so
add has the same value as before passing it to Test.
// crashes here ?

Probably. You should pass a pointer to your pointer and change
that value:
void Test( void **add, char st[2] )
and use *a=tt;
Pass *a as Test(&a,"ab")
and you should set a to NULL before calling Test.

Sorry, I forgot to mention: it's good to initialize pointers to
NULL just in case, but this initialization is not required in
this case (as opposed to the original one) because you are
passing &a to Test as opposed to a, and &a is valid as the
address of a.
 
C

CBFalconer

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

But i don't it crashes.

Please help,

cheers -mark

#include <stdlib.h>
#include <stdio.h>
#include <cmath>

no such header file.
//#include <map>
#include <string>

no such header file.

If your compiler didn't object to the above, you are using a C++
compiler, which is not a good thing to do to C code.
 
P

pete

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

But i don't it crashes.

Please help,

cheers -mark

#include <stdlib.h>
#include <stdio.h>
#include <cmath>

//#include <map>
#include <string>

void Test( void *add, char st[2] )
{
char *tt = new char[3];
strcpy( tt, st );
add = (void*)tt;
printf( ">> %s\n", (char*)add );
//free( tt );
}

int main( int argc, char **argv )
{
void *a;
Test( a, "ab" );
// crashes here ?
printf( "<< %c\n", *((char*)a + 1 ) );

char *ttt = new char[3];
strcpy( ttt, "ab" );
a = (void*)ttt;
printf( "<< %c\n", *((char*)a + 1 ) );

return 0;
}

/* BEGIN new.c */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void *Test(char *st)
{
char *tt = malloc(strlen(st) + 1);

if (tt != NULL) {
strcpy(tt, st );
printf( ">> %s\n", tt);
}
return tt;
}

int main(void)
{
void *a;
char *ttt;

a = Test("ab");
if (a != NULL) {
printf( "<< %c\n", *((char*)a + 1 ) );
}
ttt = malloc(sizeof "ab");
if (ttt != NULL) {
strcpy(ttt, "ab");
a = ttt;
printf( "<< %c\n", *((char*)a + 1 ) );
}
return 0;
}

/* END new.c */
 
M

Martin Ambuhl

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

After cleaning up your C++-isms, you will still have a logical error in
the way you call your Test() function. Please examine the following
carefully, comparing it to your original.


#include <stdlib.h>
#include <stdio.h>

#if 0
/* mha: apart from the problems of using '//' style comments in usenet
postings, no matter what the language, and with using them with C89
or C90 compilers, where they are errors, commenting out code is best
done with the #if / #endif form exemplified here. */
#include <map>
#endif

#if 0
/* mha: there are no headers named <cmath> or <string> in C. */
#include <cmath>
#include <string>
#endif
#include <string.h> /* mha */

void Test(void **add /* mha: NB */ , char st[2])
{
#if 0
/* mha: the following is a syntax error in C. A replacement follows.
It appears that your function provides no way to report failures. */
char *tt = new char[3];
#endif
char *tt;
if (!(tt = malloc(3))) {
fprintf(stderr, "%s",
"malloc failed, and 'Test()' provides no way to "
"handle that.\nI'm giving up.\n");
exit(EXIT_FAILURE);
}
strcpy(tt, st);
*add = tt; /* mha: NB */
printf(">> %s\n", (char *) *add);

/* mha: it is a good thing you don't free tt; In your off-topic
C++-ism you allocate it with new. Such things are freed with
delete or delete[], not with free(). */
// free( tt );

}

int main(void)
{
void *a;
Test(&a, "ab"); /* mha: NB */
printf("<< %c\n", *((char *) a + 1));
{
#if 0
/* mha: declaration following executable statements in the block
is an error in C89 or C90. I have added a block. */
/* mha: the following is a syntax error in C. A replacement
follows. */
char *ttt = new char[3];
#endif
char *ttt;
if (!(ttt = malloc(3))) {
fprintf(stderr, "%s",
"malloc failed in main(),\nI'm giving up.\n");
free(a);
exit(EXIT_FAILURE);
}
strcpy(ttt, "ab");
a = (void *) ttt;
printf("<< %c\n", *((char *) a + 1));
/* mha: Please clean up after yourself. */
free(ttt); /* mha */
}
/* mha: Please clean up after yourself. */
free(a); /* mha */
return 0;
}
 
J

jaysome

I almost apologize to ask this question but I have been starting at
this code for a bit of time and don't understand what's wrong with it.
I am not arguing about the fact it's good or not coding, it's actually
a shorter version of something more complex that i am doing.

Anway the idea is that there's a func Test which takes a pointer to
void argument, allocate some memory, set this memory with some cotent,
assign the ptr to a void to the first byte of this new alloc memory
and returuns. Normally because our argument points to the first byte
of that memory array * AND THAT THE MEM HASN'T BEEN FREED *, i should
still be able to access the content of that mem array.

After cleaning up your C++-isms, you will still have a logical error in
the way you call your Test() function. Please examine the following
carefully, comparing it to your original.


#include <stdlib.h>
#include <stdio.h>

#if 0
/* mha: apart from the problems of using '//' style comments in usenet
postings, no matter what the language, and with using them with C89
or C90 compilers, where they are errors, commenting out code is best
done with the #if / #endif form exemplified here. */
#include <map>
#endif

#if 0
/* mha: there are no headers named <cmath> or <string> in C. */
#include <cmath>
#include <string>
#endif
#include <string.h> /* mha */

void Test(void **add /* mha: NB */ , char st[2])
{
#if 0
/* mha: the following is a syntax error in C. A replacement follows.
It appears that your function provides no way to report failures. */
char *tt = new char[3];
#endif
char *tt;
if (!(tt = malloc(3))) {
fprintf(stderr, "%s",
"malloc failed, and 'Test()' provides no way to "
"handle that.\nI'm giving up.\n");
exit(EXIT_FAILURE);
}
strcpy(tt, st);
*add = tt; /* mha: NB */
printf(">> %s\n", (char *) *add);

/* mha: it is a good thing you don't free tt; In your off-topic
C++-ism you allocate it with new. Such things are freed with
delete or delete[], not with free(). */
// free( tt );

}

int main(void)
{
void *a;
Test(&a, "ab"); /* mha: NB */
printf("<< %c\n", *((char *) a + 1));
{
#if 0
/* mha: declaration following executable statements in the block
is an error in C89 or C90. I have added a block. */
/* mha: the following is a syntax error in C. A replacement
follows. */
char *ttt = new char[3];
#endif
char *ttt;
if (!(ttt = malloc(3))) {
fprintf(stderr, "%s",
"malloc failed in main(),\nI'm giving up.\n");
free(a);
exit(EXIT_FAILURE);
}
strcpy(ttt, "ab");
a = (void *) ttt;
printf("<< %c\n", *((char *) a + 1));
/* mha: Please clean up after yourself. */
free(ttt); /* mha */

Same effect as:

free(a);
}
/* mha: Please clean up after yourself. */
free(a); /* mha */

Ouch. This free()'s a pointer that has already been free()'d. Not sure
if this is what you intended.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,282
Latest member
RoseannaBa

Latest Threads

Top