473,396 Members | 2,013 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

problems with dynamic allocation in an ellipses function

Hello all

I'm pretty new to C, so please accept my apologies in advance :-)

I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!

void printStrings(s1, ...){ //ellipses function
....
....
void *myList;
int count=1;
char *pArr=s1;
va_start(myList, s1);
while( myList ){
pArr = (char *) realloc(pArr, ++count * sizeoff(char*));
assert(pArr);
pArr[count-1] = va_arg(myList, char*);
}

However, if i take the 2 lines of the allocation and assertion out of
he while, it works!!!
i.e. - the following is OK :

void *myList;
int count=1;
char *pArr=s1;
va_start(myList, s1);

pArr = (char *) realloc(pArr, ++count * sizeoff(char*));
assert(pArr); //THIS IS OK

even if i put these two lines in a for loop that run just once, it
fails!!!

int count=1;
char *pArr=s1;
va_start(myList, s1);
for(i =0; i <1; i++){ // LOOP RUNS JUST ONCE
pArr = (char *) realloc(pArr, ++count * sizeoff(char*));
assert(pArr); //ASSERTION FAILS HERE!!!
}

what Am i doing wrong and why is the allocation failing inside the
while/for loops

Thanks a lot
Shiron

Mar 27 '07 #1
18 1584
hyperboogie said:
Hello all

I'm pretty new to C, so please accept my apologies in advance :-)

I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!

void printStrings(s1, ...){ //ellipses function
...
...
void *myList;
int count=1;
char *pArr=s1;
va_start(myList, s1);
while( myList ){
pArr = (char *) realloc(pArr, ++count * sizeoff(char*));
Make sure you have #include <stdlib.hnear the top of your source file,
lose the cast, use a temp, and get sizeof right:

char *tmp = realloc(pArr, ++count * sizeof *pArr);
if(tmp != NULL)
{
pArr = tmp;
assert(pArr);
In C90, assert requires an integer expression:

assert(pArr != NULL);

but this is not a good way to check whether the allocation succeeded, as
it will abort the application on failure if NDEBUG is not defined, and
will ignore the failure otherwise!
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 27 '07 #2
On Mar 27, 8:54 pm, Richard Heathfield <r...@see.sig.invalidwrote:
hyperboogie said:
Hello all
I'm pretty new to C, so please accept my apologies in advance :-)
I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!
void printStrings(s1, ...){ //ellipses function
...
...
void *myList;
int count=1;
char *pArr=s1;
va_start(myList, s1);
while( myList ){
pArr = (char *) realloc(pArr, ++count * sizeoff(char*));

Make sure you have #include <stdlib.hnear the top of your source file,
lose the cast, use a temp, and get sizeof right:

char *tmp = realloc(pArr, ++count * sizeof *pArr);
if(tmp != NULL)
{
pArr = tmp;
assert(pArr);

In C90, assert requires an integer expression:

assert(pArr != NULL);

but this is not a good way to check whether the allocation succeeded, as
it will abort the application on failure if NDEBUG is not defined, and
will ignore the failure otherwise!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.
Sorry - it doesn't work ....
in any case .... why should I lose the cast? realloc returns void
* and pArr is char * , so a cast is required ... or am I wrong?

Mar 27 '07 #3
On 27 Mar, 19:38, "hyperboogie" <hyperboo...@gmail.comwrote:
Hello all

I'm pretty new to C, so please accept my apologies in advance :-)

I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!

void printStrings(s1, ...){ //ellipses function
...
...
void *myList;
int count=1;
char *pArr=s1;
va_start(myList, s1);
while( myList ){
pArr = (char *) realloc(pArr, ++count * sizeoff(char*));

My guess:

You are attempting to realloc the memory pointed to by pArr. The
first time through the loop, pArr == s1.

If you are calling with something like:

printStrings("This is the string which will be pointed to by s1",
etc., etc., ...

....then I think there's a good chance that the string "This is the
string which will be pointed to by s1" will have static storage/be
read-only due to string pooling/etc.* So I don't think that
realloc'ing this memory is valid.

* I've no doubt got the terminology wrong, but give it ten minutes and
you'll soon see a hundred people correct me!

Hope that helps,
Doug

Mar 27 '07 #4
On 27 Mar, 20:05, "hyperboogie" <hyperboo...@gmail.comwrote:
in any case .... why should I lose the cast? realloc returns void
* and pArr is char * , so a cast is required ... or am I wrong?- Hide quoted text -
I think that if you include <stdlib.hthen you don't need the cast -
you are permitted to assign void * to any pointer type.

With that in place, the cast then just hides potential problems.

Doug

Mar 27 '07 #5
hyperboogie wrote:
Hello all

I'm pretty new to C, so please accept my apologies in advance :-)

I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!

void printStrings(s1, ...){ //ellipses function
....
....
void *myList;
int count=1;
char *pArr=s1;
What is s1? If it isn't a char* allocated by malloc, all bets are off.

--
Ian Collins.
Mar 27 '07 #6
On Mar 27, 9:37 pm, Ian Collins <ian-n...@hotmail.comwrote:
hyperboogie wrote:
Hello all
I'm pretty new to C, so please accept my apologies in advance :-)
I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!
void printStrings(s1, ...){ //ellipses function
....
....
void *myList;
int count=1;
char *pArr=s1;

What is s1? If it isn't a char* allocated by malloc, all bets are off.

--
Ian Collins.
s1 is just a string. the function was called from main like so:

printStrings("father", "mother", "brother", "sister", NULL);

one correction to what I wrote earlier:
The function is printStrings(char* s1, ...){...}

Mar 27 '07 #7
On Mar 27, 9:36 pm, "Doug" <DougTheS...@googlemail.comwrote:
On 27 Mar, 20:05, "hyperboogie" <hyperboo...@gmail.comwrote:
in any case .... why should I lose the cast? realloc returns void
* and pArr is char * , so a cast is required ... or am I wrong?- Hide quoted text -

I think that if you include <stdlib.hthen you don't need the cast -
you are permitted to assign void * to any pointer type.

With that in place, the cast then just hides potential problems.

Doug
I have added <stdlib.hand tried it with and without the cast - no
difference.

Mar 27 '07 #8
On 27 Mar, 20:49, "hyperboogie" <hyperboo...@gmail.comwrote:
s1 is just a string. the function was called from main like so:

printStrings("father", "mother", "brother", "sister", NULL);

one correction to what I wrote earlier:
The function is printStrings(char* s1, ...){...}- Hide quoted text -
Well, this is your problem. In your call to printStrings(), "father"
is not a dynamically allocated piece of memory. Thus, you cannot
realloc it.

Doug

Mar 27 '07 #9
On 27 Mar, 20:51, "hyperboogie" <hyperboo...@gmail.comwrote:
On Mar 27, 9:36 pm, "Doug" <DougTheS...@googlemail.comwrote:
On 27 Mar, 20:05, "hyperboogie" <hyperboo...@gmail.comwrote:
in any case .... why should I lose the cast? realloc returns void
* and pArr is char * , so a cast is required ... or am I wrong?- Hide quoted text -
I think that if you include <stdlib.hthen you don't need the cast -
you are permitted to assign void * to any pointer type.
With that in place, the cast then just hides potential problems.
Doug

I have added <stdlib.hand tried it with and without the cast - no
difference.
The cast here is not your main problem (and it won't actually affect
this exact code). But it's not good style.

Doug

Mar 27 '07 #10
hyperboogie wrote:

s1 is just a string. the function was called from main like so:

printStrings("father", "mother", "brother", "sister", NULL);

one correction to what I wrote earlier:
The function is printStrings(char* s1, ...){...}
For the future, post a complete, minimal program that demonstrates the
problem.

That statement contains three conditions:

1. Complete - A program that can be cut and pasted into our compilers
if we choose, but at the very least we know is not missing anything.

2. Minimal - The program is reduced down as much as possible. That
means removing parts where you can to simplify it, but where it still
produces the failing behavior. Often the process will reveal the
section with the bug, but at least you will make the review process
easier.

3. Demonstrates the problem - The code you give us should be able to
produce the exact condition you are experiencing. In addition, you need
to tell us what the program was supposed to do, and what it did
instead. If it is failing to compile, transcribe exactly or
(preferably) cut and paste the compiler messages.

Brian

Mar 27 '07 #11
On Mar 27, 9:55 pm, "Doug" <DougTheS...@googlemail.comwrote:
On 27 Mar, 20:49, "hyperboogie" <hyperboo...@gmail.comwrote:
s1 is just a string. the function was called from main like so:
printStrings("father", "mother", "brother", "sister", NULL);
one correction to what I wrote earlier:
The function is printStrings(char* s1, ...){...}- Hide quoted text -

Well, this is your problem. In your call to printStrings(), "father"
is not a dynamically allocated piece of memory. Thus, you cannot
realloc it.

Doug
Thanks a lot Doug
you were right - that was the problem. I also should have declared
pArr as char ** (as apposed to just char *).
everything works fine now :-)
in any case, i still don't understand why I should not use a cast.
After all, realloc returns a:
void *

Mar 27 '07 #12
hyperboogie wrote:
On Mar 27, 9:37 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>hyperboogie wrote:
>>>Hello all
>>>I'm pretty new to C, so please accept my apologies in advance :-)
>>>I'm trying to allocate space for an array of pointers to strings
(which are accepted as ellipses) inside a while loop, and after the
allocation, when i "assert" the allocation, the assertion fails!!!
>>>void printStrings(s1, ...){ //ellipses function
....
....
void *myList;
int count=1;
char *pArr=s1;

What is s1? If it isn't a char* allocated by malloc, all bets are off.
*Please* don't quote signatures!
>
s1 is just a string. the function was called from main like so:

printStrings("father", "mother", "brother", "sister", NULL);
So there's your problem.
one correction to what I wrote earlier:
The function is printStrings(char* s1, ...){...}
That should realy be:

printStrings( const char* s1, ...);

if s1 is a string literal format string.

--
Ian Collins.
Mar 27 '07 #13
hyperboogie wrote:
in any case, i still don't understand why I should not use a cast.
After all, realloc returns a:
void *
You don't need a cast to convert between void* to another pointer type,
that's the way the language is defined.

--
Ian Collins.
Mar 27 '07 #14
hyperboogie wrote:
>
.... snip ...
>
Sorry - it doesn't work ....
in any case .... why should I lose the cast? realloc returns
void * and pArr is char * , so a cast is required ... or am I wrong?
Yes, you are wrong. See the C-faq.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Mar 27 '07 #15

"hyperboogie" <hy*********@gmail.comwrote in message
news:11**********************@d57g2000hsg.googlegr oups.com...
On Mar 27, 9:55 pm, "Doug" <DougTheS...@googlemail.comwrote:
>On 27 Mar, 20:49, "hyperboogie" <hyperboo...@gmail.comwrote:
s1 is just a string. the function was called from main like so:
printStrings("father", "mother", "brother", "sister", NULL);
one correction to what I wrote earlier:
The function is printStrings(char* s1, ...){...}- Hide quoted text -

Well, this is your problem. In your call to printStrings(), "father"
is not a dynamically allocated piece of memory. Thus, you cannot
realloc it.

Doug

Thanks a lot Doug
you were right - that was the problem. I also should have declared
pArr as char ** (as apposed to just char *).
everything works fine now :-)
in any case, i still don't understand why I should not use a cast.
After all, realloc returns a:
void *
Consider what happens when you compile this on a 64-bit platform that
has 32-bit int.

If you use
char *x = (char *)malloc(n);
and forgot to #include <stdlib.h>, then there is no prototype for malloc
and the compiler assumes that it returns an int. But malloc returns void*,
which is probably 64 bits, not 32 bits. The compiler assumes malloc is
returning only 32 bits, so that's what it does, clipping the rest.
Then you cast it to a pointer, and you are now corrupt - only half of the
address has been stored in x. Bad news.

If you did not cast it, the compiler would warn you that you are trying to
set a pointer to an int. This would be your clue that something is wrong,
and hopefully you would realize the omission of the prototype.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Aero Stability and Controls Computing
Mar 27 '07 #16
hyperboogie wrote:
On Mar 27, 9:36 pm, "Doug" <DougTheS...@googlemail.comwrote:
>On 27 Mar, 20:05, "hyperboogie" <hyperboo...@gmail.comwrote:
>>in any case .... why should I lose the cast? realloc returns void*
and pArr is char * , so a cast is required ... or am I wrong?

I think that if you include <stdlib.hthen you don't need the cast
- you are permitted to assign void * to any pointer type.
.... snip ...
>
I have added <stdlib.hand tried it with and without the cast - no
difference.
If you still get error messages either you have other errors, the
compiler is faulty (doubtful) or you are using a C++ compiler
(probable). Make sure the source file extension is (lowercase) .c.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 28 '07 #17
On 27 Mar 2007 12:51:10 -0700, "hyperboogie" <hy*********@gmail.com>
wrote:
>On Mar 27, 9:36 pm, "Doug" <DougTheS...@googlemail.comwrote:
>On 27 Mar, 20:05, "hyperboogie" <hyperboo...@gmail.comwrote:
in any case .... why should I lose the cast? realloc returns void
* and pArr is char * , so a cast is required ... or am I wrong?- Hide quoted text -

I think that if you include <stdlib.hthen you don't need the cast -
you are permitted to assign void * to any pointer type.

With that in place, the cast then just hides potential problems.

Doug

I have added <stdlib.hand tried it with and without the cast - no
difference.
It may not be obvious but there is a world of difference. Without
stdlib (or a suitable prototype from some other source) any call to
malloc, with or without the cast, invokes undefined behavior under
C90. Under C99, with or without the cast, it is a constraint
violation requiring a diagnostic. In either case, not something you
want.
Remove del for email
Mar 28 '07 #18
On 27 Mar 2007 11:38:37 -0700, "hyperboogie" <hy*********@gmail.com>
wrote:
void printStrings(s1, ...){ //ellipses function
Nit: that punctuation is an ellipsis (i not e) and specifies a
variadic or varargs function.
void *myList;
int count=1;
char *pArr=s1;
As already noted, this is not something you can realloc below, and
it's also not the right type to store a series of pointers (char*) as
you apparently want to. One way to do that would be:
char * * pArr = malloc (sizeof(char*) /* * 1 */);
or the equivalent
char * * pArr = malloc (sizeof *pArr);
which many people here prefer since it automatically adapts to type
changes for you; (either) followed by:
if( pArr == NULL /* or ! pArr */ ) some error handling;
pArr[0] = s1;
va_start(myList, s1);
while( myList ){
This is a totally wrong way to try to find out what was passed. The
va_list type isn't guaranteed to be usable as a predicate at all, and
if it can be on your implementation, it isn't guaranteed to and almost
certainly won't become false. There is no Standard way for the varargs
mechanism to tell the callee how many arguments there are (or their
types) although SOME preStandard versions did. Your callee code must
(be able to) determine that BEFORE invoking va_arg on a nonexistent
argument, which causes Undefined Behavior, which is Bad (tm
Heathfield?). Three common ways to do this are:
#1- pass an explicit count.
#2- pass information that encodes the count and if necessary types,
such as the format strings used by *printf and *scanf.
#3- after the last real/valid argument pass a sentinel value that the
callee can recognize. For a sequence of pointers such as your case, a
null pointer is usually a good sentinel value. In this case the call
should be written as (char*)NULL (or a macro therefor) -- one of the
few places you SHOULD use a cast since a variadic argument is the only
place that will not automatically be converted, other than
unprototyped calls which you normally should not use.
pArr = (char *) realloc(pArr, ++count * sizeoff(char*));
assert(pArr);
pArr[count-1] = va_arg(myList, char*);
}
Apr 15 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Tom | last post by:
What I mean is why can I only allocate const size stuff on the stack in C++? If I want to allocate a variable amount I need to use the OS API (Win32 in my case). Thanks, Tom.
6
by: chris | last post by:
Hi all, I need to know, what is the difference between dynamic memory allocation, and stack allocation ? 1. If I have a class named DestinationAddress, when should I use dynamic memory...
13
by: xian_hong2046 | last post by:
Hello, I think dynamic memory allocation is supposed to be used when one doesn't know in advance how much memory to allocate until run time. An example from Thinking in C++ is to dynamically...
11
by: toton | last post by:
Hi, I have little confusion about static memory allocation & dynamic allocation for a cluss member. I have class like class Bar{ public: explicit Bar(){ cout<<"bar default"<<endl; }
24
by: Ken | last post by:
In C programming, I want to know in what situations we should use static memory allocation instead of dynamic memory allocation. My understanding is that static memory allocation like using array...
7
by: Jo | last post by:
Hi, How can i differentiate between static and dynamic allocated objects? For example: void SomeFunction1() { CObject *objectp = new CObject; CObject object;
1
by: Peterwkc | last post by:
Hello all expert, i have two program which make me desperate bu after i have noticed the forum, my future is become brightness back. By the way, my problem is like this i the first program was...
14
by: vivek | last post by:
i have some doubts on dynamic memory allocation and stacks and heaps where is the dynamic memory allocation used? in function calls there are some counters like "i" in the below function. Is...
18
by: squaretriangle | last post by:
Is it possible through some trickery, perhaps using the methods of stdarg, to pass a dynamic (unknown at compile time) number of arguments to a function? For example, I want to enumerate an array...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.