473,386 Members | 1,832 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,386 software developers and data experts.

Pointer confusion with passing string array -- Segmentation fault

I'm trying to create a function that given a string, tokenize it and
put into a dynamically-sized array of char* which is in turn also
dynamically allocated based on the string token length.

I call the function using this code fragement in my main function:
---
char** arg_array;
arg_count = create_arg_array(command, argument, arg_array);

for(count = 0; count < arg_count; count++)
printf("arg_array[%d]: %s\n", count, arg_array[count]);
---
And it always crashes with a segmentation fault when going into the
for loop to print out the array of strings. Why does it crash when
I've already called malloc and realloc (inside create_arg_array()
function) to reserve some memory for the string array?

The create_arg_array is given below.
What's wrong with this function?
---
size_t create_arg_array(char* file, char* arg, char** array){
size_t count;
char* argument;

count = 1;
/* 1 for the filename and 1 for the terminating NULL ptr. */
array = (char**) malloc(count * sizeof(char*));

array[0] = (char*) malloc(strlen(file) + 1);
strcpy((*array)[0], file);

if(arg != NULL){
argument = strtok(arg, " \n");
if(argument != NULL){
array = (char**) realloc(array, (count + 1) * sizeof(char*));
array[count] = (char*) malloc(strlen(argument) + 1);
strcpy(array[count], argument);
count++;
}
while((argument = strtok(NULL, " \n")) != NULL){
array = (char**) realloc(array, (count + 1) * sizeof(char*));
array[count] = (char*) malloc(strlen(argument) + 1);
strcpy(array[count], argument);
count++;
}
}
++count;
array = (char**) realloc(array, (count * sizeof(char*)));
array[count-1] = NULL;

return count-1; /* Minus 1 for the ending NULL */
}
---
I thought the address returned by realloc and malloc is lost when I
return to main function and I've also tried changing the function to
accept a pointer to the array of string (char***) but it doesn't help.

Any advice appreciated.
Thank you.

Goh, Yong Kwang
Singapore
go**********@hotmail.com
Nov 14 '05 #1
3 2826
On 2 Apr 2004 17:31:23 -0800, go**********@hotmail.com (Goh, Yong
Kwang) wrote in comp.lang.c:
I'm trying to create a function that given a string, tokenize it and
put into a dynamically-sized array of char* which is in turn also
dynamically allocated based on the string token length.

I call the function using this code fragement in my main function:
---
char** arg_array;
arg_count = create_arg_array(command, argument, arg_array);

for(count = 0; count < arg_count; count++)
printf("arg_array[%d]: %s\n", count, arg_array[count]);
---
And it always crashes with a segmentation fault when going into the
for loop to print out the array of strings. Why does it crash when
I've already called malloc and realloc (inside create_arg_array()
function) to reserve some memory for the string array?

The create_arg_array is given below.
What's wrong with this function?
The main answer to your primary question is covered in this
newsgroup's FAQ, specifically:

http://www.eskimo.com/~scs/C-faq/q4.8.html
---
size_t create_arg_array(char* file, char* arg, char** array){
size_t count;
char* argument;

count = 1;
/* 1 for the filename and 1 for the terminating NULL ptr. */
array = (char**) malloc(count * sizeof(char*));

array[0] = (char*) malloc(strlen(file) + 1);


Casting the pointer returned by malloc() is unnecessary in C and
considered bad form by most experienced C programmers. At best it is
useless, a redundant cast. At worst it silences an important compiler
diagnostic if you neglected to include <stdlib.h> to have a proper
prototype in scope.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #2


Goh, Yong Kwang wrote:
I'm trying to create a function that given a string, tokenize it and
put into a dynamically-sized array of char* which is in turn also
dynamically allocated based on the string token length.

..........snip...........
---
size_t create_arg_array(char* file, char* arg, char** array){
size_t count;
char* argument;
---
I thought the address returned by realloc and malloc is lost when I
return to main function and I've also tried changing the function to
accept a pointer to the array of string (char***) but it doesn't help.


A char *** parameter would be correct. But you need to correct
the logic errors. Another approach would be to define a
data type that will contain all the data that you need.

like:
typedef struct DATA
{
char *fdata /* contents of the entire file */
char **pdata /* An array of pointers to the file data */
size_t count /* A count of the array of pointers */
} DATA;

Then you can write functions to manipulate this datatype.

Ex.

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

#define FNAME "test.txt" /* File name goes here */

/*test.txt contents:

Bill:JOHN:HARRY:AL:WILLIAM:
FRANK:LARRY:RON

*/

typedef struct DATA
{
char *fstring;
char **pstring;
size_t count;
} DATA;

DATA getDATA(const char *fname, const char *delim);
void freeDATA(DATA *p);
void printDATA(DATA *p);

int main(void)
{
DATA data = getDATA(FNAME, ":\n");

printDATA(&data);
freeDATA(&data);
return 0;
}

DATA getDATA(const char *fname, const char *delim)
{
FILE *fp;
DATA p = {NULL};
char *tmp, buf[64], **tmpp;
size_t sz;

if((fp = fopen(fname,"r")) == NULL) return p;
for(sz = 0 ; (fgets(buf,sizeof buf, fp)); )
{
tmp = realloc(p.fstring, (sz += strlen(buf))+1);
if(tmp == NULL)
{
freeDATA(&p);
break;
}
if(!p.fstring) *tmp = '\0';
p.fstring = tmp;
strcat(p.fstring,buf);
}
fclose(fp);
if(p.fstring)
{
for(tmp = strtok(p.fstring,delim) ; tmp;
tmp = strtok(NULL,delim))
{
tmpp = realloc(p.pstring, (p.count+1)*sizeof(*tmpp));
if(tmpp == NULL)
{
freeDATA(&p);
break;
}
tmpp[p.count++] = tmp;
p.pstring = tmpp;
}
}
return p;
}

void freeDATA(DATA *p)
{
free(p->fstring);
free(p->pstring);
p->fstring = NULL;
p->pstring = NULL;
p->count = 0;
return;
}

void printDATA(DATA *p)
{
size_t i;

for(i = 0; i < p->count; i++)
printf("%u. %s\n",i,p->pstring[i]);
return;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #3
On 2 Apr 2004 17:31:23 -0800, go**********@hotmail.com (Goh, Yong
Kwang) wrote:
I'm trying to create a function that given a string, tokenize it and
put into a dynamically-sized array of char* which is in turn also
dynamically allocated based on the string token length.

I call the function using this code fragement in my main function:
---
char** arg_array;
arg_count = create_arg_array(command, argument, arg_array);
After you return from create_arg_array, arg_array has not been updated
with the address that was malloc'ed in the function. C always passes
by value.

for(count = 0; count < arg_count; count++)
printf("arg_array[%d]: %s\n", count, arg_array[count]);
---
And it always crashes with a segmentation fault when going into the
for loop to print out the array of strings. Why does it crash when
I've already called malloc and realloc (inside create_arg_array()
function) to reserve some memory for the string array?

The create_arg_array is given below.
What's wrong with this function?
---
size_t create_arg_array(char* file, char* arg, char** array){
size_t count;
char* argument;

count = 1;
/* 1 for the filename and 1 for the terminating NULL ptr. */
array = (char**) malloc(count * sizeof(char*));
Don't cast the return from malloc. It cannot help and can hurt.

array[0] = (char*) malloc(strlen(file) + 1);
strcpy((*array)[0], file);

if(arg != NULL){
argument = strtok(arg, " \n");
if(argument != NULL){
array = (char**) realloc(array, (count + 1) * sizeof(char*));
array[count] = (char*) malloc(strlen(argument) + 1);
strcpy(array[count], argument);
count++;
}
while((argument = strtok(NULL, " \n")) != NULL){
array = (char**) realloc(array, (count + 1) * sizeof(char*));
array[count] = (char*) malloc(strlen(argument) + 1);
strcpy(array[count], argument);
count++;
}
}
++count;
array = (char**) realloc(array, (count * sizeof(char*)));
array[count-1] = NULL;

return count-1; /* Minus 1 for the ending NULL */
}
---
I thought the address returned by realloc and malloc is lost when I
return to main function and I've also tried changing the function to
accept a pointer to the array of string (char***) but it doesn't help.
Yes it does if you use it properly. Your calling statement needs to
specify &arg_array. Inside the function, every place you currently
use array you need to use (*array). This will cause the function to
automatically update arg_array in the calling function.

Any advice appreciated.
Thank you.

Goh, Yong Kwang
Singapore
go**********@hotmail.com


<<Remove the del for email>>
Nov 14 '05 #4

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

Similar topics

13
by: xuatla | last post by:
I encountered "segmentation fault" and I checked my code, found the following problem: I want to reallocate memory for an array. I defined the following function: int reallocateMemory( double...
3
by: Goh, Yong Kwang | last post by:
I'm trying to create a function that given a string, tokenize it and put into a dynamically-sized array of char* which is in turn also dynamically allocated based on the string token length. I...
25
by: No Such Luck | last post by:
Hi all: Below are two pieces of code that basically perform the same task. Version A produces a segmentation fault, while version B works correctly. I understand why version B works correctly,...
4
by: entitledX | last post by:
Hi, I'm trying to use the HDF library to read a few HDF files that I need to process. The data in each file varies in rows, but the columns remain constant. Because of that, I had dynamically...
31
by: Newbie | last post by:
Hi, I'm a newbie. I need to clear my pointer concepts. the code below gives segmentation fault when i use char* str; int main() { char *str; printf("Enter a string to reverse\n");...
8
by: Ben | last post by:
Hi, I am having trouble debugging a segmentation fault...here's my data structure: typedef struct CELL *pCELL; /* Pointers to cells */ struct CELL { SYMBOL symbol; pCELL prev_in_block;...
25
by: dis_is_eagle | last post by:
Hi.I have a question on the following statement. char* a="hello"; The question is where "hello" gets stored.Is it in some static area ,stack or heap.I have observed that attempting to modify...
4
by: Christian Maier | last post by:
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
10
by: H.S. | last post by:
Hello, I have class in which I am allocating space for a double array in the constructor. I use the double array twice in one of the methods and then delete that array in the class's destructor....
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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...

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.