473,238 Members | 1,721 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,238 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 2813
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: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
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...

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.