473,505 Members | 16,940 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Newbee needs once more again help with passing arrays out of a function

Hi

After surfing a while I have still trouble with this array thing. I
have the following function and recive a Segmentation fault, how must
I code this right??

Thanks
Christian Maier
void fetchIds(llong *ids, char **names)
{
llong rC = 0;
llong i = 0;
char resultSet1[21]; //max. Length of a long long+1
char resultSet2[129];

rC = PQntuples( get_result() ) ;

ids[rC];
names[rC][129];

printf("Rows: %d\n", rC);
while (fetch(resultSet1, resultSet2) != END_OF_TUPLES) //
loop through all rows returned
{
//This works fine
printf("%s, %s <\n", resultSet1, resultSet2);

// ---This is segmentation fault <--- ???
//names[i] = resultSet2;
//ids[i]=strtoll(resultSet1,NULL,0);
i++;
}

}

int argc, char *argv[])
{
llong *ids;
char **mNames;

doquery("select provider_id, caption from fi.provider");
fetchIds(ids, mNames);

return 0;
}

Feb 17 '07 #1
4 2492

Christian Maier wrote:
Hi

After surfing a while I have still trouble with this array thing. I
have the following function and recive a Segmentation fault, how must
I code this right??

Thanks
Christian Maier
void fetchIds(llong *ids, char **names)
{
llong rC = 0;
llong i = 0;
llong is not defined in standard C. I'm assuming it's an alias for
long long. If not then you need to show us the relevant declaration.
char resultSet1[21]; //max. Length of a long long+1
I don't see how you conclude that. long long is atleast 64 bits. But
the string representation of LLONG_MAX needn't be twenty characters.
char resultSet2[129];

rC = PQntuples( get_result() ) ;

ids[rC];
names[rC][129];
You don't show us the definitions for PQntuples, ids and names.
Hopefully they're all correct.
printf("Rows: %d\n", rC);
The printf format specifier for long long is %lld or it's variants
like %llx etc.
while (fetch(resultSet1, resultSet2) != END_OF_TUPLES) //
loop through all rows returned
{
//This works fine
printf("%s, %s <\n", resultSet1, resultSet2);
Hopefully both resultSet1 and resultSet2 are nul terminated.
// ---This is segmentation fault <--- ???
//names[i] = resultSet2;
//ids[i]=strtoll(resultSet1,NULL,0);
You don't show us your definitions for names and ids, so we can't
really help you. Based on it's usage a few lines above, names seems to
be a two-dimensional array. In the above code you're using it with a
single index.

It also looks as if ids needs to be a two-D array.
i++;
}

}

int argc, char *argv[])
{
llong *ids;
char **mNames;

doquery("select provider_id, caption from fi.provider");
fetchIds(ids, mNames);

return 0;
}
Please post a minimal compilable subset of your code that exhibits the
error. Please cut and paste, don't retype. From what you've posted,
it's nearly impossible to tell what's causing the fault.

Feb 17 '07 #2
Christian Maier wrote:
Hi

After surfing a while I have still trouble with this array thing. I
have the following function and recive a Segmentation fault, how must
I code this right??
[...]
int argc, char *argv[])
Generally speaking, it's best to copy and paste a compilable program
into your message, to avoid problems like this. This is a syntax
error, of course, because int main( got left out for some reason.
{
llong *ids;
char **mNames;

doquery("select provider_id, caption from fi.provider");
fetchIds(ids, mNames);
"ids" and "mNames" are pointers. They can contain the starting address
of some region in memory, but they can only reliably do that if you
give them the starting address of some region in memory. Look up the
malloc function to fix this.

(I haven't looked too closely to see if the rest of your program
should work properly.)
return 0;
}
Feb 17 '07 #3
On Feb 17, 11:39 pm, "Christian Maier" <tomtai...@freesurf.frwrote:
Hi

After surfing a while I have still trouble with this array thing. I
have the following function and recive a Segmentation fault, how must
I code this right??

Thanks
Christian Maier

void fetchIds(llong *ids, char **names)
{
llong rC = 0;
llong i = 0;
char resultSet1[21]; //max. Length of a long long+1
char resultSet2[129];

rC = PQntuples( get_result() ) ;

ids[rC];
names[rC][129];

printf("Rows: %d\n", rC);
while (fetch(resultSet1, resultSet2) != END_OF_TUPLES) //
loop through all rows returned
{
//This works fine
printf("%s, %s <\n", resultSet1, resultSet2);

// ---This is segmentation fault <--- ???
//names[i] = resultSet2;
//ids[i]=strtoll(resultSet1,NULL,0);
i++;
}

}

int argc, char *argv[])
{
llong *ids;
char **mNames;

doquery("select provider_id, caption from fi.provider");
fetchIds(ids, mNames);

return 0;

}
Hi,

You haven't given too much information, so I can only guess at what
could be happening. But a couple of things stick out. Like Harald
pointed out, the pointers ids, mNames need to be initialized. I'm
assuming that you have some code to take care of that, which you're
not showing us. The other thing that looks dangerous to me is
"names[i] = resultSet2;".

resultSet2 is a local variable. As a rule of thumb, local variables
are stored on the stack, which, for the purposes of this discussion,
means that the memory allocated for a local variable is deallocated
(note that this is an over-simplification) once the function "ends".
When you say names[i] = resultSet2, you're copying the address of
resultSet2 (an address that is only going to be valid while you're
"inside" fetchIds) into names[i]. I am guessing that your intention is
to actually copy the data, not the address, in which case, you should
probably use something like "strncpy(names[i], resultSet2, MAX_LEN);".
Of course, names[i] will have to be "properly" allocated memory.

If this doesn't solve your problem, please post a complete, yet brief,
snippet, isolating the problem and we can try to see what really going
wrong.

Feb 18 '07 #4
Christian Maier <to*******@freesurf.frwrote:
After surfing a while I have still trouble with this array thing. I
have the following function and recive a Segmentation fault, how must
I code this right??
There are a lot of things no clear from the code you posted, e.g.
what exactly the functions you use do, what their return values
are, what llong is etc. So in trying to write something useful
I will have to make a lot of assumptions that may not be true.
Please keep that in mind.

I will go through the code first and make a few comments and then
try to give you a version that may be somewhat nearer to what you
are going to need.
void fetchIds(llong *ids, char **names)
Here are already several problems. First of all, it looks as
if you want to pass back an array of integers and an array of
strings to the calling function (or pointers to these arrays
to be precise) where the memory for the arrays will get allo-
cated within this function. And in this case you need the value
of e.g. 'ids' to be set and have the new value passed back to
the caller. This won't work when this function just gets an
llong pointer - arguments get passed by value in C, so what-
ever changes you do to 'ids' in this function won't be visible
in the caller. If you want to change 'ids' in a way that can be
seen by the caller you need to pass a pointer to that pointer
and treat it accordingly in this function. The same holds for
'names'. The second problem is that you seem to determine the
number of elements of these arrays in this function but the
caller isn't going to know what that is, and you won't be able
to use those arrays in the caller without that knowledge. You
must return that length either via another argument or as the
return value of the function.
{
llong rC = 0;
llong i = 0;
char resultSet1[21]; //max. Length of a long long+1
This seems to indicate that llong is a 64-bit long long, at
least 21 chars are exactly the right amount for that case
(2^63 is about 9.2e18, so 19 chars are needed for that plus
one for a minus sign and another one for the trailing '\0').
char resultSet2[129];
I've got to believe you that 129 chars will always be enough
rC = PQntuples( get_result() ) ;
Looks like this function returns the number of calls of fetch()
you can do.
ids[rC];
names[rC][129];
Now that won't make it past your compiler as you probably have
seen;-) It looks a lot as if you would like to allocate memory
for an array of llongs and another one for some kind of 2-dimen-
sional array (I write "some kind" since a 2-dimensional array is
*not* of type pointer to pointer, but that's what 'names' is).
printf("Rows: %d\n", rC);
Since 'rC' seems to be a long long you will need '%lld' here
as the conversion specifier.
while (fetch(resultSet1, resultSet2) != END_OF_TUPLES) //
loop through all rows returned
Can you be 100% sure that this condition is true for not more than
'rC' times? And I hope that we can assume that both 'resultSet1'
and 'resultSet2' are properly '\0'-terminated strings.
{
//This works fine
printf("%s, %s <\n", resultSet1, resultSet2);

// ---This is segmentation fault <--- ???
//names[i] = resultSet2;
You will need to use strcopy() or something similar here. A simple
assignment just copies the address of 'resultSet2' and not the
string in 'resultSet2'. Moreover, once you left the function, that
address has gone out of scope and can't be used anymore.
//ids[i]=strtoll(resultSet1,NULL,0);
i++;
}

}

int argc, char *argv[])
{
llong *ids;
char **mNames;

doquery("select provider_id, caption from fi.provider");

fetchIds(ids, mNames);

return 0;
}
Ok, as promised, here's a version that hopefully will be a bit more
like what you are going to need (of course only if the assumptions
I had to make aren't too far off the mark):

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

#define llong long long

llong fetchIds( llong **ids, char ***names )
{
llong rC = 0;
llong i;
char resultSet1[ 21 ];
char resultSet2[ 129 ];
llong *l_ids; /* temporary variables that make */
char ** l_names; /* things a bit easier to read */

rC = PQntuples( get_result( ) ) ;

/* Get memory for an array of 'rC' llongs - lets hope that the
number of bytes will always be in the range of size_t, one
could ceck for that to be 100% safe. */

if ( ( l_ids = malloc( rC * sizeof *l_ids ) ) == NULL )
{
fprintf( stderr, "Not enough memory, bailing out.\n" );
exit( EXIT_FAILURE );
}

/* Get memory for an array of 'rC' char pointers */

if ( ( l_names = malloc( rC * sizeof *l_names ) ) == NULL )
{
fprintf( stderr, "Not enough memory, bailing out.\n" );
exit( EXIT_FAILURE );
}

printf( "Rows: %lld\n", rC );

/* Loop until either fetch() has been called 'rC' times or its
return value indicates that we're done */

for ( i = 0;
i < rC && fetch( resultSet1, resultSet2 ) != END_OF_TUPLES;
i++ )
{
/* First we need memory for the string we're going to copy.
The address gets stored in the ith element of the array
of char pointers we allocated before. And instead of
129 (as in the origional code) the length of the string
we're going to copy is used in order to avoid allocating
more memory than necessary. */

l_names[ i ] = malloc( ( strlen( resultSet2 ) + 1 ) *
sizeof **l_names );
if ( l_names[ i ] == NULL )
{
fprintf( stderr, "Not enough memory, bailing out.\n" );
exit( EXIT_FAILURE );
}

strcpy( l_names[ i ], resultSet2 );

/* Probably one should do some error checking for the next
line - strtoll() could fail for some reason like the
string to be converted not containing a number */

l_ids[ i ] = strtoll( resultSet1, NULL, 0 );
}

/* Now that we're done the addresses of the newly allocated
arrays get stored in the argument pointers. */

*ids = l_ids;
*names = l_names;

/* Return how many times we called fetch() successfully and
thus how many elements in both the arrays have been set. */

return i;
}

int main( void )
{
llong rows;
llong *ids;
char **mNames;
llong i;

/* Call fetchIds() with the addresses of both the pointers so
that the values of the pointers can be changed from within
that function. */

rows = fetchIds( &ids, &mNames );

/* Print out what we just got */

for ( i = 0; i < rows; i++ )
printf( "%lld =%s\n", ids[ i ], mNames[ i ] );

/* Sometime later you will have to get rid of the memory that
was allocated in fetchIds(). That can be done like this: */

for ( i = 0; i < rows; i++ )
free( mNames[ i ] );
free( mNames );
free( ids );

return EXIT_SUCCESS;
}

Please note again: 'mNames' is not a 2-dimensional array like one
that you would define like this

char real_2d_array[ 123 ][ 129 ];

Instead 'mNames' is an array of char pointers and each of these char
pointers stored in 'mNames' points in turn to an array of chars (or,
to be precise, the first element of the char array). See also the
C-FAQ (section 6.16) about this

http://c-faq.com/aryptr/dynmuldimary.html

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Feb 18 '07 #5

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

Similar topics

5
12596
by: harry | last post by:
I have 2 multi-dim arrays double subTotals = null; String rowTitles = null; I want to pass them to a function that initialises & populates them like so - loadData( rowTitles, subTotals);
58
10048
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
8
2057
by: Foxy Kav | last post by:
Hi everyone, Im currently doing first year UNI, taking a programming course in C++, for one project i have to create a simple array manipulator... that i have done, but i cant figure out how to...
2
1948
by: dave.harper | last post by:
I'm relatively new to C++, but have a question regarding functions and arrays. I'm passing a relatively large array to a function several thousand times during the course of a loop, and it seems...
4
1771
by: PerryC | last post by:
All, 1. Do the following codes seem ok? 2. If so, then how do I pull the value of YOE1 and YOE2 into my report? (to do some further calculations) ...
2
4290
by: Morgan | last post by:
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...
5
1617
by: jeremy targett | last post by:
Hello, in my program I use 2-dimensional arrays to hold two integer values for each of i members of a list. array holds a starting position, and array holds a label - in fact I #defined START as 0...
39
19557
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
2
1721
by: Rene | last post by:
Hello to all! I am a newbee to C++, I did a beginners' course, and now I am stuck with a strange problem. I have written the function that is pasted downwards. The peculiar thing is that when...
0
7218
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
7103
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
5614
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,...
1
5035
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
4701
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3188
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1532
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
755
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
409
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.