vc.user_comments[i] = string; /*crashing*/

T

Tatu Portin

Have this kind of struct:

typedef struct {
char **user_comments;
/* ... */
} vorbis_comment;

/* prototype */
char * read_vorbis_string
( FILE *sc);

/* problem */
vc.user_comments = read_vorbis_string (sc);

'read_vorbis_string' returns a pointer to a calloced string. This function
works for sure.
But the problem is, that 'vc.user_comments = string;' is not the right way
to assing the address of the 'string' to the pointer array 'vc.user_comments'.
What is?
 
K

karl malbrain

Tatu Portin said:
Have this kind of struct:

typedef struct {
char **user_comments;
/* ... */
} vorbis_comment;

/* prototype */
char * read_vorbis_string
( FILE *sc);

/* problem */
vc.user_comments = read_vorbis_string (sc);

'read_vorbis_string' returns a pointer to a calloced string. This function
works for sure.
But the problem is, that 'vc.user_comments = string;' is not the right way
to assing the address of the 'string' to the pointer array 'vc.user_comments'.
What is?


You've left out the INSTANTIATION of vorbis_comment. Please post this
section, where you declare and initialize vc.

karl m
 
T

Tatu Portin

karl said:
Have this kind of struct:

typedef struct {
char **user_comments;
/* ... */
} vorbis_comment;

/* prototype */
char * read_vorbis_string
( FILE *sc);

/* problem */
vc.user_comments = read_vorbis_string (sc);

'read_vorbis_string' returns a pointer to a calloced string. This function
works for sure.
But the problem is, that 'vc.user_comments = string;' is not the right
way

to assing the address of the 'string' to the pointer array
'vc.user_comments'.

What is?



You've left out the INSTANTIATION of vorbis_comment. Please post this
section, where you declare and initialize vc.

karl m


Here is your "INSTANTIATION":

vorbis_comment read_comments
( const char *scname)
{
/* After second 'vorbis' string comes the width (int) of VENDOR string.
* Then comes the VENDOR string itself.
* After VENDOR string comes the number (int) of comments.
* After the number of comments comes the width (int) of first user comment.
* After the first user comment comes the width (int) of the second user comment.
*/
register int i;

vorbis_comment vc;
FILE *sc;
char *ident = "vorbis";

sc = fopen (scname, "rb");
assert (sc != NULL);

assert (!wind_till (ident, sc));
assert (!wind_till (ident, sc));

vc.vendor = read_vorbis_string (sc);
assert (vc.vendor != NULL);

assert (fread (&vc.comments, sizeof (int), 1, sc) == 1);

printf ("%d\n", vc.comments);

vc.comment_wds = (int *) calloc (vc.comments + 1, sizeof (int));
assert (vc.comment_wds != NULL);

for (i = 0 ; i < vc.comments - 1 ; i++) {
vc.user_comments = read_vorbis_string (sc);

assert (vc.user_comments != NULL);
printf ("__%s__", vc.user_comments);

vc.comment_wds = strlen (vc.user_comments);
}

vc.comment_wds[vc.comments + 1] = 0;


return vc;
}
/* End Of File */
 
T

Tatu Portin

Problem solved.

I hadn't calloced memory for the array of pointers. I was only callocing memory
for the strings which the array of pointers should be pointing to.

/* ... */

assert (fread (&vc.comments, sizeof (int), 1, sc) == 1);

printf ("%d\n", vc.comments);

/* ADDED */
vc.user_comments = (char *) calloc (vc.comments + 1, sizeof (char *));
assert (vc.user_comments != NULL);
/* End of ADDED */

vc.comment_wds = (int *) calloc (vc.comments + 1, sizeof (int));
assert (vc.comment_wds != NULL);
/* ... */
 
C

CBFalconer

Tatu said:
Have this kind of struct:

typedef struct {
char **user_comments;
/* ... */
} vorbis_comment;

/* prototype */
char * read_vorbis_string
( FILE *sc);

/* problem */
vc.user_comments = read_vorbis_string (sc);

'read_vorbis_string' returns a pointer to a calloced string. This
function works for sure.

But the problem is, that 'vc.user_comments = string;' is not
the right way to assing the address of the 'string' to the pointer
array 'vc.user_comments'. What is?


You haven't shown a complete compilable program, which forces
anyone replying to make assumptions (or to ignore you). There is
no declaration of vc. Assuming one exists in scope, of the form:

vorbis_comment vc;

vc.user_comments is of type char **, i.e a pointer to a pointer to
a char. It is uninitialized, and any use of it will cause
undefined behaviour. Don't ask me what you should initialize it
to, since you didn't bother making your program and specifications
complete. I suspect you want a linked list rather than an array.
 
T

Tatu Portin

CBFalconer said:
Tatu said:
Have this kind of struct:

typedef struct {
char **user_comments;
/* ... */
} vorbis_comment;

/* prototype */
char * read_vorbis_string
( FILE *sc);

/* problem */
vc.user_comments = read_vorbis_string (sc);

'read_vorbis_string' returns a pointer to a calloced string. This
function works for sure.

But the problem is, that 'vc.user_comments = string;' is not
the right way to assing the address of the 'string' to the pointer
array 'vc.user_comments'. What is?



You haven't shown a complete compilable program, which forces
anyone replying to make assumptions (or to ignore you). There is
no declaration of vc. Assuming one exists in scope, of the form:

vorbis_comment vc;

vc.user_comments is of type char **, i.e a pointer to a pointer to
a char. It is uninitialized, and any use of it will cause
undefined behaviour. Don't ask me what you should initialize it
to, since you didn't bother making your program and specifications
complete. I suspect you want a linked list rather than an array.


Here is the complete working program. (compiled -Wall -pedantic)

/* Start Of File */

/* Public Domain */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

/* CDmaker
* Purpose is to correctly rip tags from Ogg Vorbis files for
* reproduction in printable form for CD distribution.
*/

typedef struct {
char **user_comments;
int *comment_wds;
int comments;
char *vendor;
} vorbis_comment;

/* 'read_comments' is a hack.
* It does not work by the specification.*/
char * read_vorbis_string
( FILE *sc);

int wind_till
( const char *ident
, FILE *sc);

vorbis_comment read_comments
( const char *scname);

int print_comments
( const vorbis_comment vc);

int main
( int argc
, char *argv[])
{
vorbis_comment vc;

vc = read_comments (argv[1]);

print_comments (vc);

return 0;
}

char * read_vorbis_string
( FILE *sc)
{
register int i;
int wd;
char *str;
char ch;

if (fread (&wd, sizeof (int), 1, sc) != 1)
return NULL;

str = (char *) calloc (wd + 1, sizeof (int));
if (str == NULL)
return NULL;

for (i = 0 ; i < wd ; i++) {
ch = fgetc (sc);
if (ch == EOF)
break;
str = ch;
}
str[wd + 1] = '\0';

return str;
}


int wind_till
( const char *ident
, FILE *sc)
{
register int i;
int ch = '\0';

if (ident[0] == '\0')
return 0;

while (1) {
for (i = 0 ; ident == ch ; i++) {
if (ident[i + 1] == '\0')
return 0;

ch = fgetc (sc);
if (ch == EOF)
return 2;

}

ch = fgetc (sc);
if (ch == EOF)
return 1;
}

return 3;
}

vorbis_comment read_comments
( const char *scname)
{
/* After second 'vorbis' string comes the width (int) of VENDOR string.
* Then comes the VENDOR string itself.
* After VENDOR string comes the number (int) of comments.
* After the number of comments comes the width (int) of first user comment.
* After the first user comment comes the width (int) of the second user comment.
*/
register int i;

vorbis_comment vc;
FILE *sc;
char *ident = "vorbis";

sc = fopen (scname, "rb");
assert (sc != NULL);

assert (!wind_till (ident, sc));
assert (!wind_till (ident, sc));

vc.vendor = read_vorbis_string (sc);
assert (vc.vendor != NULL);

assert (fread (&vc.comments, sizeof (int), 1, sc) == 1);

/* Allocate memory for pointers */
vc.user_comments = (char **) calloc (vc.comments + 1, sizeof (char *));
assert (vc.user_comments != NULL);

/* Allocate memory for comment lenghts */
vc.comment_wds = (int *) calloc (vc.comments + 1, sizeof (int));
assert (vc.comment_wds != NULL);

for (i = 0 ; i < vc.comments ; i++) {
vc.user_comments = read_vorbis_string (sc);
assert (vc.user_comments != NULL);

vc.comment_wds = strlen (vc.user_comments);
}

vc.comment_wds[vc.comments + 1] = 0;


return vc;
}

int print_comments
( vorbis_comment vc)
{
register int i;

printf ("%s, %d comments\n", vc.vendor, vc.comments);

for (i = 0 ; i < vc.comments ; i++) {
printf ("%d: \t%s\n"
, vc.comment_wds
, vc.user_comments
);
}

return i;
}
/* End Of File */
 
H

honeygrl33

Wow guys...... this is CMSC 100... so lost.... :-\ no pointers just
arrays and i'm only 19 i dont get all that!!
 
H

honeygrl33

what's vorbis? Here's my entire program:
/*
*/

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

#define SIZE 12

void printResults (char months[][15], double sales[]);
void storeSales (char months[][15], double sales[]);

int main ( void )
{
system ("clear");
int i;
double sales[ SIZE ];
char months [SIZE][15] = {"January", "February", "March", "April",
"May",
"June", "July", "August", "September",
"October",
"November", "December"};

for (i = 0; i < SIZE; i++)
{
printf("%-9s: %9.2f\n", months[ i ], sales[ i ]);
}
storeSales (months, sales);
printResults (months, sales);
return 0;

}
void storeSales ( char months[][15], double sales[] )
{
int i = 0;
for ( i = 0; i < SIZE; i++ )
{

do
{
printf("Enter the store's sales for the month of %s:",
months[ i ]);
scanf( "9.2%lf", &sales [ i ]);
printf("\n");
}
while ((sales[ i ] < 0.00 ) || ( sales[ i ] > 100000.00));
}
}


void printResults ( char months[][15], double sales[] )
{
int i;
double lowest = 0.0, highest = 0.0, average = 0.0;

for (i = 0 ; i < SIZE ; i++)
average = average + (sales / SIZE);


printf ("Average of the store's sales: %lf\n", average);


lowest = sales[0];
for (i = 0 ; i < SIZE ; i++) {
if (lowest > sales) {
lowest = sales;
}
}


printf ("Lowest sales month: %lf\n", lowest);


highest = sales[0];
for (i = 0 ; i < SIZE ; i++) {
if (highest < sales) {
highest = sales;
}
}


printf ("Highest sales month: %lf\n", highest);
return;
}
 
H

honeygrl33

/*
*/

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

#define SIZE 12

void printResults (char months[][15], double sales[]);
void storeSales (char months[][15], double sales[]);

int main ( void )
{
system ("clear");
double sales[ SIZE ];
char months [SIZE][15] = {"January", "February", "March", "April",
"May",
"June", "July", "August", "September", "October",
"November", "December"};


storeSales (months, sales);
printResults (months, sales);
return 0;

}
void storeSales ( char months[][15], double sales[] )
{
int i = 0;
for ( i = 0; i < SIZE; i++ )
{

do
{
printf("Enter the store's sales for the month of %s:", months[ i ]);
scanf( "9.2%lf", &sales [ i ]);
printf("\n");
}
while ((sales[ i ] < 0.00 ) || ( sales[ i ] > 100000.00));
}
}


void printResults ( char months[][15], double sales[] )
{
int i;
double lowest = 0.0, highest = 0.0, average = 0.0;

for (i = 0; i < SIZE; i++)
{
printf("%-9s: %9.2f\n", months[ i ], sales[ i ]);
}

for (i = 0 ; i < SIZE ; i++)
average = average + (sales / SIZE);


printf ("Average of the store's sales: %lf\n", average);


lowest = sales[0];
for (i = 0 ; i < SIZE ; i++) {
if (lowest > sales) {
lowest = sales;
}
}


printf ("Lowest sales month: %lf\n", lowest);


highest = sales[0];
for (i = 0 ; i < SIZE ; i++) {
if (highest < sales) {
highest = sales;
}
}


printf ("Highest sales month: %lf\n", highest);
return;
}

I see what you mean, I did it.. but after compilation and entering
sales for January it's stuck in the loop??? it says "Enter sales for
January" until I press ctrl C!
 
M

Mark McIntyre


<snip code>

When posting code, you need to post some sort of question too. Why did you
post this? Whats your problem? What do you want people to help with?

Do NOT rely on people having access to posts you made several days ago.
 
C

CBFalconer

Mark said:
<snip code>

When posting code, you need to post some sort of question too. Why
did you post this? Whats your problem? What do you want people to
help with?

Do NOT rely on people having access to posts you made several days
ago.

In fact don't rely on access to ANY other posts. Many get lost, or
delayed for days and weeks. Usenet is a 'no guarantees'
mechanism. Therefore snip quotations down to the portion germane
to your answer, and answer after the quoted portion.
 

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

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,405
Latest member
DavidCex

Latest Threads

Top