By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,091 Members | 1,555 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,091 IT Pros & Developers. It's quick & easy.

Why char** dynamic_string_array(int ROWS, int SIZE) doesn't work properly?

P: n/a
Hi,please help...
It works fine when I define a 2-D array like char code[ROWS][SIZE].
But it won't work when I try to define the array dynamically using a
function. It just crashes.
Does anyone know why?
The compiler i'm using is Dev c++.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int file_length(FILE *file);
void down_string(char *p);
char* issubstring(char *str1,char *str2);
char** dynamic_string_array(int ROWS, int SIZE);

int main(void)
{
int row,n,i,coursefound=0,ROWS,SIZE,test;

FILE *datafile;
datafile=fopen("3rdyear.csv", "rb");
ROWS=file_length(datafile);

printf("Has %d lines\n",ROWS);

char **Code,**Course,**ClassSize,**Time1,**Time2,**Room ,c;
char search[30];
Code=dynamic_string_array(ROWS,SIZE);
Course=dynamic_string_array(ROWS,SIZE);
ClassSize=dynamic_string_array(ROWS,SIZE);
Time1=dynamic_string_array(ROWS,SIZE);
Time2=dynamic_string_array(ROWS,SIZE);
Room=dynamic_string_array(ROWS,SIZE);
for (row=0; row <ROWS; row++) {
test=fscanf(datafile, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]\n",
Code[row],Course[row],ClassSize[row],
Time1[row],Time2[row],Room[row]);
printf("row=%d,scanf converted %d (%s,%s,%s,%s,%s,%s)\n",
row, test,

Code[row],Course[row],ClassSize[row],Time1[row],Time2[row],Room[row]);
}
printf("Please enter a name\n>");
scanf("%s",search);
for(i=1; i<ROWS; i++) {
if(issubstring(Course[i],search)) {
coursefound=1;
printf("Course %s found!!\nTime 1 is %s\nTime2 is
%s\nVenue:%s",Course[i],Time1[i],Time2[i],Room[i]);

}
}
if(coursefound==0) printf("No such Course!.\n");
fclose(datafile);
return EXIT_SUCCESS;

}
void down_string(char *p) //turns uppercase letters in a string to
lowercase
{
int i;
for(i=0;p[i]!='\0';i++)
{
if((p[i]>='A')&&(p[i]<='Z')) p[i]+=32;
}
}
char* issubstring(char *str1,char *str2) //checks if string2 is a
substring of string2
{
char tmp1[30],tmp2[30];
strcpy(tmp1, str1);
strcpy(tmp2, str2);
down_string(tmp1); //turn it to lowercase
down_string(tmp2);
return (strstr(tmp1, tmp2));
}

char** dynamic_string_array(int ROWS, int SIZE)
{
char **array;
int i;
array=(char**) malloc(ROWS*sizeof(char));
for(i=0;i<ROWS;i++)
array[i]=(char *) malloc(SIZE*sizeof(char));

return array;
}
int file_length(FILE *file)
{
int lines;
char dummy[100];

rewind(file);

lines=0;
while( fgets(dummy, 100, file) != NULL)
lines++;

rewind(file);

return(lines);
}

Nov 14 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
In article <11**********************@o13g2000cwo.googlegroups .com>,
<dd*************@yahoo.co.uk> wrote:
:It works fine when I define a 2-D array like char code[ROWS][SIZE].
:But it won't work when I try to define the array dynamically using a
:function. It just crashes.
:Does anyone know why?

:char** dynamic_string_array(int ROWS, int SIZE)
:{
: char **array;
: int i;
: array=(char**) malloc(ROWS*sizeof(char));

You probably want malloc(ROWS*sizeof(char*))
seeing as you are going to be storing in character pointers.

: for(i=0;i<ROWS;i++)
: array[i]=(char *) malloc(SIZE*sizeof(char));
:
: return array;
:}
--
Would you buy a used bit from this man??
Nov 14 '05 #2

P: n/a
dd*************@yahoo.co.uk wrote:
Hi,please help...
It works fine when I define a 2-D array like char code[ROWS][SIZE].
But it won't work when I try to define the array dynamically using a
function. It just crashes.
Does anyone know why?
The compiler i'm using is Dev c++.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int file_length(FILE *file);
void down_string(char *p);
char* issubstring(char *str1,char *str2);
char** dynamic_string_array(int ROWS, int SIZE);

int main(void)
{
int row,n,i,coursefound=0,ROWS,SIZE,test;

FILE *datafile;
datafile=fopen("3rdyear.csv", "rb");
ROWS=file_length(datafile);

printf("Has %d lines\n",ROWS);

char **Code,**Course,**ClassSize,**Time1,**Time2,**Room ,c;
char search[30];
Code=dynamic_string_array(ROWS,SIZE);


SIZE has not been initialized. Perhaps your compiler could have been so
kind as to help you with that...

foo.c:12: warning: `SIZE' might be used uninitialized in this function

-David
Nov 14 '05 #3

P: n/a


dd*************@yahoo.co.uk wrote:
Hi,please help...
It works fine when I define a 2-D array like char code[ROWS][SIZE].
But it won't work when I try to define the array dynamically using a
function. It just crashes.
Does anyone know why?
The compiler i'm using is Dev c++.


Code snipped.

The code provided here does not compile. The code has numerous
errors. I think it would probably be best to take a step
back and rethink the problem. First, I would decide
on what data structure I need to store the data. Then
write functions that manipulate this data structure.
There are several ways to model the data structure.
Here is an example of one way.

First, make a struct where you can store the data for the class.
typedef struct CLASS
{
char *data;
char *code;
char *course;
char *size;
char *time1;
char *time2;
char *room;
} CLASS;

Then a struct that has as member, an array of class (ex. of the school)
and a member that represents the number of classes.

typedef struct CLASSARR
{
CLASS *class;
size_t cnt;
} CLASSARR;
Then write a function that will add a class and
a function that will print the class array. Test these
functions. Then add other functions that manipulates the data
structure one, or few, at a time, and test them out before
continuing. Then, if you come to a problem that you cannot
solve, the newsgroup can focus and better able to help you.

Example:

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

#define MAXLINE 100

typedef struct CLASS
{
char *data;
char *code;
char *course;
char *size;
char *time1;
char *time2;
char *room;
} CLASS;

typedef struct CLASSARR
{
CLASS *class;
size_t cnt;
} CLASSARR;

int AddCLASSARR(CLASSARR *p, const char *s);
int ParseClassData(CLASS *p, char *data);
void PrintCLASSARR(CLASSARR *p);
void FreeCLASSARR(CLASSARR *p);

int main(void)
{
CLASSARR myschool = {NULL};
FILE *fp;

AddCLASSARR(&myschool,"3511,English,32,8:00am,10:0 0am,130");
AddCLASSARR(&myschool,"2511,Calculus,21,9:00am,12: 00am,141");
puts("\tTest Data");
PrintCLASSARR(&myschool);
FreeCLASSARR(&myschool);
/* Test on a data file */
puts("\n\tData from a file");
if((fp = fopen("test.txt","r")) != NULL)
{
char buf[MAXLINE];
size_t i;
for(i = 0 ; (fgets(buf,MAXLINE,fp)); i++)
if(!AddCLASSARR(&myschool,buf))
printf("Error in File: Line %u\n",i+1);
fclose(fp);
PrintCLASSARR(&myschool);
FreeCLASSARR(&myschool);
}
else puts("Unable to open the file to read data");
return 0;
}

int AddCLASSARR(CLASSARR *p, const char *cs)
{
CLASS *tmp;
char *s;

if((s = malloc(strlen(cs)+1)) == NULL) return 0;
strcpy(s,cs);
tmp = realloc(p->class,(p->cnt+1)*sizeof *tmp);
if(!tmp)
{
free(s);
return 0;
}
p->class = tmp;
if(!ParseClassData(&p->class[p->cnt],s))
{
free(s);
return 0;
}
p->cnt++;
return 1;
}

int ParseClassData(CLASS *p, char *data)
{
int i;
char *s, *tmp[6];

s = strtok(data,",\n");
for(i = 0;(s);i++)
{
if(i < 6) tmp[i] = s;
s = strtok(NULL,",\n");
}
if(i != 6) return 0;
p->code = tmp[0];
p->course = tmp[1];
p->size = tmp[2];
p->time1 = tmp[3];
p->time2 = tmp[4];
p->room = tmp[5];
p->data = data;
return 1;
}

void PrintCLASSARR(CLASSARR *p)
{
size_t i;

for(i = 0; i < p->cnt;i++)
printf("Code: %s\nCourse: %s\nSize: %s\n"
"Time1: %s\nTime2: %s\nRoom: %s\n\n",
p->class[i].code, p->class[i].course,
p->class[i].size,p->class[i].time1,
p->class[i].time2, p->class[i].room);
return;
}

void FreeCLASSARR(CLASSARR *p)
{
size_t i;

for(i = 0; i < p->cnt; i++) free(p->class[i].data);
free(p->class);
p->class = NULL;
p->cnt = 0;
return;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <11**********************@o13g2000cwo.googlegroups .com>,
<dd*************@yahoo.co.uk> wrote:
:It works fine when I define a 2-D array like char code[ROWS][SIZE].
:But it won't work when I try to define the array dynamically using a
:function. It just crashes.
:Does anyone know why?

:char** dynamic_string_array(int ROWS, int SIZE)
:{
: char **array;
: int i;
: array=(char**) malloc(ROWS*sizeof(char));

You probably want malloc(ROWS*sizeof(char*))
seeing as you are going to be storing in character pointers.


There's no need to cast the result of malloc() in C. (Two people in
this newsgroup will disagree with that; one has good reasons to write
code that compiles both as C and as C++, the other is wrong.)

It's also a good idea, in a malloc() call, to use the size of what the
result points to, not the size of a type that can change or that you
can get wrong.

The best way to do the above is:

array = malloc(ROWS * sizeof *array);

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #5

P: n/a
Sorry i had sent the wrong version, so it had a few minor errors.
But the problem in question was solved by replacing sizeof(char) with
sizeof(*array) as you adviced.
Thanks.
Keith Thompson wrote:
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <11**********************@o13g2000cwo.googlegroups .com>,
<dd*************@yahoo.co.uk> wrote:
:It works fine when I define a 2-D array like char code[ROWS][SIZE]. :But it won't work when I try to define the array dynamically using a :function. It just crashes.
:Does anyone know why?

:char** dynamic_string_array(int ROWS, int SIZE)
:{
: char **array;
: int i;
: array=(char**) malloc(ROWS*sizeof(char));

You probably want malloc(ROWS*sizeof(char*))
seeing as you are going to be storing in character pointers.
There's no need to cast the result of malloc() in C. (Two people in
this newsgroup will disagree with that; one has good reasons to write
code that compiles both as C and as C++, the other is wrong.)

It's also a good idea, in a malloc() call, to use the size of what

the result points to, not the size of a type that can change or that you
can get wrong.

The best way to do the above is:

array = malloc(ROWS * sizeof *array);

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do

this.

Nov 14 '05 #6

P: n/a
dd*************@yahoo.co.uk wrote:

char* issubstring(char *str1,char *str2) //checks if string2 is a
substring of string2
{
char tmp1[30],tmp2[30];
strcpy(tmp1, str1);
strcpy(tmp2, str2);
down_string(tmp1); //turn it to lowercase
down_string(tmp2);
return (strstr(tmp1, tmp2));
}


What happens when the strings are longer than 29 characters?

You'd be better off to roll your own stristr function that
doesn't need to allocate any memory.

Nov 14 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.