473,324 Members | 2,473 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,324 software developers and data experts.

Realloc() with 2D arrays; returning multiple values

Hello,

I am writing a function that populates an array of pointers to
strings. Both the number of strings in the array, and the lengths of
the strings, are dynamic; in particular, the number of strings won't
be known until just before the function returns.

The problem is that in the calling function, I need to know both the
address of the array, and the number of strings. My first thought was
to pass a pointer to the array into the function, and return a size_t
which is the number of strings. That way, I know the address of the
array to begin with, and I get the number of strings when the function
returns. But since I realloc() within the function, I change the
address of the array, so the address in the calling function is no
longer correct.

At this point, I think that I'll need to create a structure to hold
both the array and the number of strings, and return a pointer to an
instance of the struct.

Is my thinking correct on this? Is there a different/better approach?

Thanks,
Anthony
http://nodivisions.com/
Nov 13 '05 #1
4 4959
Anthony wrote:

Hello,

I am writing a function that populates an array of pointers to
strings. Both the number of strings in the array, and the lengths of
the strings, are dynamic; in particular, the number of strings won't
be known until just before the function returns.

The problem is that in the calling function, I need to know both the
address of the array, and the number of strings. My first thought was
to pass a pointer to the array into the function, and return a size_t
which is the number of strings. That way, I know the address of the
array to begin with, and I get the number of strings when the function
returns. But since I realloc() within the function, I change the
address of the array, so the address in the calling function is no
longer correct.

At this point, I think that I'll need to create a structure to hold
both the array and the number of strings, and return a pointer to an
instance of the struct.

Is my thinking correct on this? Is there a different/better approach?


Unless you have a C99 compiler you're not going to be
able to put the array itself inside a struct. But in any
version of C you can put a pointer to the array inside the
struct, viz:

struct stringinfo {
char **stringarray;
size_t stringcount;
};

There's more than one way to use a gizmo of this kind,
too. As you mention, the function could return a pointer
to a struct like this. It could also just plain return the
entire struct as its value:

struct stringinfo func( /* args */ ) {
struct stringinfo result;
...
result.stringarray = ...;
result.stringcount = ...;
return result;
}

Still another possibility is to have the caller create the
struct, pass a pointer to it as one of the function arguments,
and let the function fill in the fields:

void func(struct stringinfo *info, /* other args */ ) {
...
info->stringarray = ...;
info->stringcount = ...;
}

If you examine this last method closely, you'll see that
the struct packaging really isn't necessary; it's just a
shorthand way of passing two arguments in one "slot." You
could instead just pass pointers to the individual items:

void func(char ***stringarray, size_t *stringcount,
/* other args */ ) {
...
*stringarray = ...;
*stringcount = ...;
}

And then there are mixed strategies, where the function
returns one datum as its value and modifies the other through
a pointer in the argument list, e.g.

char **func(size_t *stringcount, /* other args */ ) {
char **stringarray;
...
*stringcount = ...;
return stringarray;
}

Personally, I'd usually prefer one of the struct-packaged
variants, because it seems comforting to keep the "thing" and
the "description" (the array and the element count) together
rather than letting them float around at random. But that's
mostly a matter of taste and/or whim, and I myself sometimes
choose a different method.

--
Er*********@sun.com
Nov 13 '05 #2
Eric Sosman <Er*********@sun.com> wrote in message news:<3F***************@sun.com>...
Unless you have a C99 compiler you're not going to be
able to put the array itself inside a struct.


Actually, there's a good chance his compiler does support this. It's a
common extension to ANSI C.

Sam
Nov 13 '05 #3
Anthony <or****@nodivisions.com> wrote:
Hello,

I am writing a function that populates an array of pointers to
strings. Both the number of strings in the array, and the lengths of
the strings, are dynamic; in particular, the number of strings won't
be known until just before the function returns.
...
Is my thinking correct on this? Is there a different/better approach?


Maybe you should try a completely other approach to the problem:
Try not to put the pointers into an array but to build a tree of some
kind. Then you can easily pass the pointer of the root node, and have the
return value free for error codes. If this approach is usefull of course
depends upon the performance you want at accessing the array/tree later.
Nov 13 '05 #4
Eric Sosman <Er*********@sun.com> wrote in message news:<3F***************@sun.com>...
Unless you have a C99 compiler you're not going to be
able to put the array itself inside a struct. But in any
version of C you can put a pointer to the array inside the
struct
Sorry for not being clear; I was saying "array" and meaning "pointer"
but I know they're not really the same thing. But yes, I meant to
store a pointer in the struct.
Still another possibility is to have the caller create the
struct, pass a pointer to it as one of the function arguments,
and let the function fill in the fields:

void func(struct stringinfo *info, /* other args */ ) {
...
info->stringarray = ...;
info->stringcount = ...;
}
This was what I'd planned to do.
If you examine this last method closely, you'll see that
the struct packaging really isn't necessary; it's just a
shorthand way of passing two arguments in one "slot." You
could instead just pass pointers to the individual items:

void func(char ***stringarray, size_t *stringcount,
/* other args */ ) {
...
*stringarray = ...;
*stringcount = ...;
}
Ah, now that's something that I didn't realize. I can pass a pointer
to the _count_ because that won't get moved by a realloc(). Then
modify that directly, and send the new array pointer as the return
value.
And then there are mixed strategies, where the function
returns one datum as its value and modifies the other through
a pointer in the argument list, e.g.

char **func(size_t *stringcount, /* other args */ ) {
char **stringarray;
...
*stringcount = ...;
return stringarray;
}
Oh. You already said all that :)
Personally, I'd usually prefer one of the struct-packaged
variants, because it seems comforting to keep the "thing" and
the "description" (the array and the element count) together
rather than letting them float around at random. But that's
mostly a matter of taste and/or whim, and I myself sometimes
choose a different method.


I think I'll try the pointer-to-the-count method first, instead of
using a struct, and see how that goes. Maybe I'll switch to the
struct method if it doesn't work out, or if the first method is so
easy that it isn't fun enough. Thanks a bunch for the help.

-Anthony
http://nodivisions.com/
Nov 13 '05 #5

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

Similar topics

12
by: Michael | last post by:
How would I go about shrinking the buffer that was allocated with new, or expanding it in place? I basically need a realloc equivalent for new. Thanks in advance. Michael
9
by: WL | last post by:
Hey, all. I'm creating an array of strings (char **argv style) on the fly, and using realloc to create string pointers, and malloc for the strings itself (if that makes any sense). I'm using the...
16
by: Martin Joergensen | last post by:
Hi, I wanted to try something which I think is a very good exercise... I read in data from the keyboard and store them in a structure. There's a pointer called "data_pointer" which I use to...
3
by: kj | last post by:
I am trying to diagnose a bug in my code, but I can't understand what's going on. I've narrowed things down to this: I have a function, say foo, whose signature looks something like: int foo(...
28
by: bwaichu | last post by:
Is it generally better to set-up a buffer (fixed sized array) and read and write to that buffer even if it is larger than what is being written to it? Or is it better to allocate memory and...
4
by: Kenneth Brody | last post by:
I looked at my copy of n1124, and I didn't see anything about this particular situation... What happens if you realloc() to a size of zero? Implementations are allowed to return NULL on...
29
weaknessforcats
by: weaknessforcats | last post by:
Arrays Revealed Introduction Arrays are the built-in containers of C and C++. This article assumes the reader has some experiece with arrays and array syntax but is not clear on a )exactly how...
9
by: Francois Grieu | last post by:
When running the following code under MinGW, I get realloc(p,0) returned NULL Is that a non-conformance? TIA, Francois Grieu #include <stdio.h> #include <stdlib.h>
1
by: Richard Harter | last post by:
On Fri, 27 Jun 2008 09:28:56 -0700 (PDT), pereges <Broli00@gmail.comwrote: There are some obvious questions that should be asked, e.g., is the contents of your array already sorted as your...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.