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

D

dddddddd2444444

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,search)) {
coursefound=1;
printf("Course %s found!!\nTime 1 is %s\nTime2 is
%s\nVenue:%s",Course,Time1,Time2,Room);

}
}
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!='\0';i++)
{
if((p>='A')&&(p<='Z')) p+=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=(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);
}
 
W

Walter Roberson

: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=(char *) malloc(SIZE*sizeof(char));
:
: return array;
:}
 
D

David Resnick

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
 
A

Al Bowers

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:00am,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 = 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.code, p->class.course,
p->class.size,p->class.time1,
p->class.time2, p->class.room);
return;
}

void FreeCLASSARR(CLASSARR *p)
{
size_t i;

for(i = 0; i < p->cnt; i++) free(p->class.data);
free(p->class);
p->class = NULL;
p->cnt = 0;
return;
}
 
K

Keith Thompson

: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);
 
D

dddddddd2444444

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 said:
: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);
San Diego Supercomputer Center <*>
We must do something. This is something. Therefore, we must do
this.
 
O

Old Wolf

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top