471,305 Members | 1,245 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,305 software developers and data experts.

*** glibc detected *** ./test: realloc(): invalid old size: 0x00007fff49779070 ***

Any comments why char **page doesn't reallocate

#include <stdlib.h>

void
add(char **page,char *line,int n)
{
char **temp;
if(temp=realloc(page,sizeof(char *)*(n+1)))
{
//malloc stuff later to add line
page=temp;
}
}

int
main(void)
{
char *s;
char *line="test1";
char *page[]={NULL};
add(page,line,1);
//free memory later
}

Jul 16 '07 #1
36 7286
On 16 Jul, 13:48, gert <gert.cuyk...@gmail.comwrote:
>
#include <stdlib.h>

void
add(char **page,char *line,int n)
{
char **temp;
if(temp=realloc(page,sizeof(char *)*(n+1)))
{
//malloc stuff later to add line
page=temp;
}

}

int
main(void)
{
char *s;
char *line="test1";
char *page[]={NULL};
add(page,line,1);
//free memory later

}
Any comments why char **page doesn't reallocate
Because you lied to realloc().

Since page is not a NULL pointer, realloc() believes it represents a
block of space allocated by malloc(). It doesn't so all bets are off.

Jul 16 '07 #2
On Jul 16, 3:04 pm, mark_blue...@pobox.com wrote:
On 16 Jul, 13:48, gert <gert.cuyk...@gmail.comwrote:
#include <stdlib.h>
void
add(char **page,char *line,int n)
{
char **temp;
if(temp=realloc(page,sizeof(char *)*(n+1)))
{
//malloc stuff later to add line
page=temp;
}
}
int
main(void)
{
char *s;
char *line="test1";
char *page[]={NULL};
add(page,line,1);
//free memory later
}
Any comments why char **page doesn't reallocate

Because you lied to realloc().

Since page is not a NULL pointer, realloc() believes it represents a
block of space allocated by malloc(). It doesn't so all bets are off.
Aha so char *page[]={NULL}; needs to be replaced with some malloc
first.
Back to drawing board.

Jul 16 '07 #3
ma**********@pobox.com wrote:
On 16 Jul, 13:48, gert <gert.cuyk...@gmail.comwrote:
>>
#include <stdlib.h>

void
add(char **page,char *line,int n)
{
char **temp;
if(temp=realloc(page,sizeof(char *)*(n+1)))
{
//malloc stuff later to add line
page=temp;
}

}

int
main(void)
{
char *s;
char *line="test1";
char *page[]={NULL};
add(page,line,1);
//free memory later

}
>Any comments why char **page doesn't reallocate

Because you lied to realloc().

Since page is not a NULL pointer, realloc() believes it represents a
block of space allocated by malloc(). It doesn't so all bets are off.
Not only that, but whatever `add` does won't affect the value of
main's `page` (C not having pass-by-reference). I suspect that
add's `page` should be a char***. I believe this is a case where
typedefing pointers [or introducing structs] makes sense:

typedef char *Line; /* a line is a pointer to a null-terminated seq of char */
typedef Line *Page; /* a page is a pointer to a seq of Line */

void addLine( Page *refPage, Line line, int linesInPageAtTheMoment )
{
Page realloced = realloc( *refPage, sizeof(Line) * (linesInPageAtTheMoment + 1) );
if (realloced) ... *refPage = realloced;
else ... deal with failure ...
}

Or `addLine` could return the new Page.

In practice I'd have a `struct page` with a `Line *lines` and an
`int count` in it. In fact, because it's usually better to
mallocated multiplicatively, it would have an `int count` and
an `int limit`.

--
Chris "mmm, marvelous malloc" Dollin

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Jul 16 '07 #4
#include <stdlib.h>

void
add(void *page,char *line,size_t n)
{
void *temp;
if(temp=realloc(page,sizeof(void *)*(n+1)))
{
//malloc stuff to add line
page=temp;
}
}

int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
add(page,line,0);
//free memory
}

BINGO! :)

Jul 16 '07 #5
gert wrote:
#include <stdlib.h>

void
add(void *page,char *line,size_t n)
{
void *temp;
if(temp=realloc(page,sizeof(void *)*(n+1)))
{
//malloc stuff to add line
page=temp;
}
}

int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
add(page,line,0);
//free memory
}

BINGO! :)
No! ;-)

Your code is not clean...
Never use "void*" when you know the type of your data !!!!

void add(char **page, char *line, int n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1))) {
page = temp;
page[n] = strdup(line);
}
}

int main(int argc, char **argv)
{
char *line = "test1";
char **page = NULL; // here is your original mistake!
add(page, line, 0);
return 0;
}

"char **x" and "char *y[]" are not the same!
x is pointer of "char*" and y is an array of "char*".
Jul 16 '07 #6
On 16 Jul, 14:57, gert <gert.cuyk...@gmail.comwrote:
#include <stdlib.h>

void
add(void *page,char *line,size_t n)
{
void *temp;
if(temp=realloc(page,sizeof(void *)*(n+1)))
{
//malloc stuff to add line
page=temp;
}

}

int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
add(page,line,0);
//free memory

}

BINGO! :)
I rather think not, in the general case anyway...

As "add" doesn't alter the value of the original "page" variable,
you'll have all manner of fun and games if you try to use it again in
your main path, for example :-

int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
add(page,line,0);
add(page,"my dog has fleas",1);
/*free memory - how? I don't know where it is....*/

}

I think Chris made some very good points... I've just hacked a version
together based on his ideas and it works nicely.

Jul 16 '07 #7
gert <ge**********@gmail.comwrote:
#include <stdlib.h>
void
add(void *page,char *line,size_t n)
{
void *temp;
if(temp=realloc(page,sizeof(void *)*(n+1)))
{
//malloc stuff to add line
page=temp;
}
}
int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
Why do you use 'void *' as the type of 'page'? A void pointer
is usually rather useless. Moreover, if you allocate memory
for a void pointer then the type of the variable you assign
it to should be pointer to pointer to void. But from your
other posts it looks as if 'page' is supposed to be pointer
to an array of char pointers (whic would make more sense)...
add(page,line,0);
Here you pass the value of 'page' to the function. The function
changes that value but the value of 'page' in main() is never
going to be influenced by this. You either have to pass a pointer
to 'page' to the function, so that it can change what 'page' is
pointing to or you could have the new value be the return value
of the function and assign that to 'page'.
//free memory
}
What about (assuming that you want 'page' to be a pointer to
an array of "strings"):

void add( char ***page_p, char *line, size_t n ) {
char **temp = *page_p;
if ( ( temp = realloc( temp, ( n + 1 ) * sizeof *temp ) ) == NULL ) {
/* Deal with failure to obtain more memory */
}

/* Do what you need to do with the new memory */
temp[ n ] = line;

*page_p = temp:
}

int main( void ) {
char *line = "test1";
char **page = NULL;
add( &page, line, 0 ); /* pass the address of 'page' so it
can be modified in the function! */
...
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jul 16 '07 #8
gert wrote:
#include <stdlib.h>

void
add(void *page,char *line,size_t n)
{
void *temp;
if(temp=realloc(page,sizeof(void *)*(n+1)))
{
//malloc stuff to add line
page=temp;
}
}

int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
add(page,line,0);
//free memory
}

BINGO! :)
UNBINGO!

Note that the value of `page` in `main` is /unchanged/.

[See my other message in thsi thread.]

--
Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England

Jul 16 '07 #9
On 16 Jul, 14:15, Chris Dollin <chris.dol...@hp.comwrote:
....
I believe this is a case where
typedefing pointers [or introducing structs] makes sense:

typedef char *Line; /* a line is a pointer to a null-terminated seq of char */
typedef Line *Page; /* a page is a pointer to a seq of Line */

void addLine( Page *refPage, Line line, int linesInPageAtTheMoment )
{
Page realloced = realloc( *refPage, sizeof(Line) * (linesInPageAtTheMoment + 1) );
if (realloced) ... *refPage = realloced;
else ... deal with failure ...
}

Or `addLine` could return the new Page.
I think that's nicer - it could return NULL to indicate a failure in
the reallocation of the page or failure to allocate space for the copy
of the line (assuming we will copy the line).
>
In practice I'd have a `struct page` with a `Line *lines` and an
`int count` in it. In fact, because it's usually better to
mallocated multiplicatively, it would have an `int count` and
an `int limit`.
Indeed... I'm probably overly inclined to object-like programming, as
I also work with Java, but I'd be inclined to split this out a bit
more and have library routines for Line and Page management, using
headers and opaque types to hide implementation details. With
apologies to Jean-MArc, that would probably mean lots of "void *"
except in the modules which really deal with Lines and Pages...

For example, I think it may be worth having stringToLine() and
lineToString() functions, so that if you wanted to move from null-
terminated strings to a mechanism which held the string length, you
could do so without changing everywhere that used Lines - only the
Line module would change.

Jul 16 '07 #10

"gert" <ge**********@gmail.comwrote in message
news:11**********************@k79g2000hse.googlegr oups.com...
#include <stdlib.h>

void
add(void *page,char *line,size_t n)
{
void *temp;
if(temp=realloc(page,sizeof(void *)*(n+1)))
It's unlikely that 'void *' is correct here.
But, since ytou don't say what it is you are trying to
accomplish, we can only guess.
You probably want 'char *'
{
//malloc stuff to add line
page=temp;
}
}

int
main(void)
{
char *line="test1";
void *page = malloc(sizeof(void *));
The above line is useless. And why are you using void*?
It looks more like you warnt a char*.
add(page,line,0);
//free memory
}

You probably want something like (not compiled or tested):

#include <stdlib.h/* Necessary to get prototype for realloc*/
#include <string.h>
void add( char **page, char *line )
{
char *temp;
if(temp=realloc( *page, (strlen(line)+strlen(*page)+1) ) )
{
strcat( temp, line );
*page = temp;
}
}

int main(void)
{
char *line="test1";
char*page = NULL;
add( &page, line );
//free memory
}
Jul 16 '07 #11
I modified the code of Jean-MArc Lienher a bit

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

void add(char **page, char *line, size_t n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
{
page = temp;
page[n] = strdup(line);
page[n+1] = NULL;
}
}

int main(int argc, char **argv)
{
size_t i;
char *line;
char *line1 = "test1";
char **page = NULL;
add(page, line, 1);
for(i=0;line=page[i];i++)
{
printf("%s",line);
free(page[i]);
}
free(page);
return 0;
}

gdb output
Starting program: /var/www/trunk/cgi/test test

Breakpoint 2, main (argc=2, argv=0x7fff84e007c8) at test.c:21
21 char *line1 = "test1";
22 char **page = NULL;
23 add(page, line, 0);

Breakpoint 1, add (page=0x0, line=0x0, n=0) at test.c:9
9 if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
11 page = temp;
12 page[n] = strdup(line);

(gdb) print page
$1 = (char **) 0x601010

(gdb) print page[1]
$2 = 0x0

(gdb) print page[0]
$3 = 0x0

Program received signal SIGSEGV, Segmentation fault.
0x00002ac125f3a640 in strlen () from /lib/libc.so.6
(gdb)

I think the best word to describe the situation right now would be
HELP?

Jul 16 '07 #12
On Jul 16, 4:19 pm, Jean-MArc Lienher <ok...@bluewin.chwrote:
No! ;-)

Your code is not clean...
Never use "void*" when you know the type of your data !!!!

void add(char **page, char *line, int n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1))) {
page = temp;
page[n] = strdup(line);
}

}

int main(int argc, char **argv)
{
char *line = "test1";
char **page = NULL; // here is your original mistake!
add(page, line, 0);
return 0;

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

void add(char **page, char *line, size_t n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
{
page = temp;
page[n] = strdup(line);
page[n+1] = NULL;
}
}

int main(int argc, char **argv)
{
size_t i;
char *line;
char *line1 = "test1";
char **page = NULL;
add(page, line, 0);
for(i=0;line=page[i];i++)
{
printf("%s",line);
free(page[i]);
}
free(page);
return 0;
}

DEBUG
9 if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
11 page = temp;
12 page[n] = strdup(line);

(gdb) print page
$1 = (char **) 0x601010

(gdb) print page[1]
$2 = 0x0

(gdb) print page[0]
$3 = 0x0

(gdb) next
Program received signal SIGSEGV, Segmentation fault.
0x00002ac125f3a640 in strlen () from /lib/libc.so.6

realloc on vacation ?

Jul 16 '07 #13
gert <ge**********@gmail.comwrites:
I modified the code of Jean-MArc Lienher a bit

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

void add(char **page, char *line, size_t n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
{
page = temp;
page[n] = strdup(line);
page[n+1] = NULL;
}
}
<snip>
I think the best word to describe the situation right now would be
HELP?
You've had some very accurate and helpful answers, but just in case
there is an element "running before you can walk" here don't go any
further until you know what this program does and why:

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

void inc(int x)
{
x = x + 1;
}

void say_goodbye(char *s)
{
s = malloc(9);
if (s) strcpy(s, "goodbye\n");
}

int main(void)
{
char *string = "Hello world\n";
int i = 42;
inc(i);
say_goodbye(string);
printf("%s %d\n", string, i);
return 0;
}

Forgive me if this is too obvious, but you have this same error in
most of your postings.

--
Ben.
Jul 16 '07 #14
On Jul 16, 5:47 pm, gert <gert.cuyk...@gmail.comwrote:
I modified the code of Jean-MArc Lienher a bit

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

void add(char **page, char *line, size_t n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
{
page = temp;
page[n] = strdup(line);
page[n+1] = NULL;
}

}

int main(int argc, char **argv)
{
size_t i;
char *line;
char *line1 = "test1";
char **page = NULL;
add(page, line, 1);
for(i=0;line=page[i];i++)
{
printf("%s",line);
free(page[i]);
}
free(page);
return 0;

}

gdb output
Starting program: /var/www/trunk/cgi/test test

Breakpoint 2, main (argc=2, argv=0x7fff84e007c8) at test.c:21
21 char *line1 = "test1";
22 char **page = NULL;
23 add(page, line, 0);

Breakpoint 1, add (page=0x0, line=0x0, n=0) at test.c:9
9 if (temp = (char**) realloc(page, sizeof(char*) * (n + 1)))
11 page = temp;
12 page[n] = strdup(line);

(gdb) print page
$1 = (char **) 0x601010

(gdb) print page[1]
$2 = 0x0

(gdb) print page[0]
$3 = 0x0

Program received signal SIGSEGV, Segmentation fault.
0x00002ac125f3a640 in strlen () from /lib/libc.so.6
(gdb)

I think the best word to describe the situation right now would be
HELP?
Sorry about the double posting, google groups is acting weird today, i
know char *page need to be referenced later on for main to be able to
print the added lines but i first want to know why my debugger says
page[0] is 0x0 instead of a reference to "test1" here ?

Jul 16 '07 #15
Jean-MArc Lienher wrote:

void add(char **page, char *line, int n)
{
char **temp;
if (temp = (char**) realloc(page, sizeof(char*) * (n + 1))) {
This cast is unnecessary, and can hide a potentially dangerous
condition, lack of a proper declaration for realloc(). The original
code had an include for <stdlib.h>, yours doesn't. Not good.
page = temp;
page[n] = strdup(line);
There is no standard C function called strdup().
}
}

int main(int argc, char **argv)
{
char *line = "test1";
char **page = NULL; // here is your original mistake!
add(page, line, 0);
return 0;
}

"char **x" and "char *y[]" are not the same!
x is pointer of "char*" and y is an array of "char*".
With respect to function parameters, they are completely equivalent.
Otherwise, the only place char *y[] could be used is in a declaration
with intializers, like:

char *y[] = {"hi", "low"}; /* bad form at that, should be const */

Brian
Jul 16 '07 #16
On Jul 16, 6:54 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
You've had some very accurate and helpful answers, but just in case
there is an element "running before you can walk" here don't go any
further until you know what this program does and why:

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

void inc(int x)
{
x = x + 1;
}

void say_goodbye(char *s)
{
s = malloc(9);
if (s) strcpy(s, "goodbye\n");

}

int main(void)
{
char *string = "Hello world\n";
int i = 42;
inc(i);
say_goodbye(string);
printf("%s %d\n", string, i);
return 0;
}

Forgive me if this is too obvious, but you have this same error in
most of your postings.
Hello world
42

Working on the program goodbye 43 that also seems to have a segment
fault :)

Jul 16 '07 #17
On Jul 16, 6:54 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
You've had some very accurate and helpful answers, but just in case
there is an element "running before you can walk" here don't go any
further until you know what this program does and why:

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

void inc(int x)
{
x = x + 1;

}

void say_goodbye(char *s)
{
s = malloc(9);
if (s) strcpy(s, "goodbye\n");

}

int main(void)
{
char *string = "Hello world\n";
int i = 42;
inc(i);
say_goodbye(string);
printf("%s %d\n", string, i);
return 0;

}

Forgive me if this is too obvious, but you have this same error in
most of your postings.

--
Ben.
i found the goodbye 43 solution :)

void inc(int *x)
{
*x = *x + 1;
}

void say_goodbye(char *s)
{
strcpy(s, "goodbye\n");
}

int main(void)
{
char *string = malloc(9);
int *i= malloc(sizeof(int));
*i=42;
inc(i);
say_goodbye(string);
printf("%s %d\n", string, *i);
return 0;
}

Jul 16 '07 #18
Jens Thoms Toerring said:
gert <ge**********@gmail.comwrote:
<snip>
> void *page = malloc(sizeof(void *));

Why do you use 'void *' as the type of 'page'? A void pointer
is usually rather useless.
Oh, my dear dear chap, how can you say such a thing? I swear by them,
really I do. If you don't want yours, feel free to pass them over -
I've always got room for another void *.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 16 '07 #19
On Jul 16, 4:49 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
What about (assuming that you want 'page' to be a pointer to
an array of "strings"):

void add( char ***page_p, char *line, size_t n ) {
char **temp = *page_p;
if ( ( temp = realloc( temp, ( n + 1 ) * sizeof *temp ) ) == NULL ) {
/* Deal with failure to obtain more memory */
}

/* Do what you need to do with the new memory */
temp[ n ] = line;

*page_p = temp:

}

int main( void ) {
char *line = "test1";
char **page = NULL;
add( &page, line, 0 ); /* pass the address of 'page' so it
can be modified in the function!
BINGO 2 :)

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

void add(char ***page, char *line, size_t n)
{
char **temp=*page;
if (temp = (char**) realloc(temp, sizeof(char*) * (n + 1)))
{
temp[n] = line;
temp[n+1] = NULL;
*page = temp;
}
}

int main(int argc, char **argv)
{
size_t i;
char *line;
char *line1 = "test1";
char **page = NULL;
add(&page, line1, 0);
for(i=0;line=page[i];i++)
{
printf("%s",line);
}
return 0;
}

PS any memory leaks in there ?

Jul 16 '07 #20
Richard Heathfield <rj*@see.sig.invalidwrote:
Jens Thoms Toerring said:
gert <ge**********@gmail.comwrote:
<snip>
void *page = malloc(sizeof(void *));
Why do you use 'void *' as the type of 'page'? A void pointer
is usually rather useless.
Oh, my dear dear chap, how can you say such a thing? I swear by them,
really I do. If you don't want yours, feel free to pass them over -
I've always got room for another void *.
I meant for as a variable for storing the address of an often
used object;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jul 16 '07 #21
gert <ge**********@gmail.comwrote:
BINGO 2 :)
PS any memory leaks in there ?
Sorry, but you're not done yet;-)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void add(char ***page, char *line, size_t n)
{
char **temp=*page;
if (temp = (char**) realloc(temp, sizeof(char*) * (n + 1)))
Do the calculations: you pass n = 0 to the function, so you
here allocate just a single char pointer.
{
temp[n] = line;
This is still fine.
temp[n+1] = NULL;
But here you assign NULL to something you haven't allocated,
you would need space for two pointers. And that's something
you definitely aren't allowed to do. It may look as every-
thing works but you have a bug there that may lead to your
program crashing (or even worse, giving you strange results)
at any time.
*page = temp;
}
You should always take into consideration the case that the
memory allocation fails, so in a "real" program you would
have to deal with that case here.
}
int main(int argc, char **argv)
{
size_t i;
char *line;
char *line1 = "test1";
char **page = NULL;
add(&page, line1, 0);
for(i=0;line=page[i];i++)
{
printf("%s",line);
}
return 0;
}
If you want to always have a NULL as the last element of the
array of char pointers then it's probably reasonable to allo-
cate memory for that at the very start of your program.

You could e.g. have a function (error checking left as an
exercise to the reader;-):

char **init( void ) {
char **p = malloc( sizeof *p );
p[ 0 ] = NULL;
return p;
}

and then use it in main() (again without error checking!) as

int main( int argc, char **argv )
{
size_t i;
char *line;
char *line1 = "test1";
char **page = init( );
...
}

Now change your add() function to reallocate (n + 2) times
the size of an char pointer (instead of just (n + 1) and
things (hopefully) should work correctly.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jul 16 '07 #22
gert <ge**********@gmail.comwrites:
On Jul 16, 4:49 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
>What about (assuming that you want 'page' to be a pointer to
an array of "strings"):

void add( char ***page_p, char *line, size_t n ) {
char **temp = *page_p;
if ( ( temp = realloc( temp, ( n + 1 ) * sizeof *temp ) ) == NULL ) {
/* Deal with failure to obtain more memory */
}

/* Do what you need to do with the new memory */
temp[ n ] = line;

*page_p = temp:

}

int main( void ) {
char *line = "test1";
char **page = NULL;
add( &page, line, 0 ); /* pass the address of 'page' so it
can be modified in the function!

BINGO 2 :)

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

void add(char ***page, char *line, size_t n)
{
char **temp=*page;
if (temp = (char**) realloc(temp, sizeof(char*) * (n + 1)))
{
temp[n] = line;
temp[n+1] = NULL;
*page = temp;
}
}

int main(int argc, char **argv)
{
size_t i;
char *line;
char *line1 = "test1";
char **page = NULL;
add(&page, line1, 0);
for(i=0;line=page[i];i++)
{
printf("%s",line);
}
return 0;
}

PS any memory leaks in there ?
I'd say that's possibly about the first time ever I saw a "***".

Maybe I just led a sheltered life or I was use to more readable code.
Jul 16 '07 #23
Richard Heathfield wrote:
Jens Thoms Toerring said:
gert <ge**********@gmail.comwrote:

<snip>
void *page = malloc(sizeof(void *));
Why do you use 'void *' as the type of 'page'? A void pointer
is usually rather useless.

Oh, my dear dear chap, how can you say such a thing? I swear by them,
really I do. If you don't want yours, feel free to pass them over -
I've always got room for another void *.
If you feed them, they'll never leave.


Brian
Jul 16 '07 #24
#BINGO RELEASE CANDIDATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char **
init(void)
{
char **p;
if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}

static void
add(char ***page, char *line, size_t n)
{
char **temp=*page;
if (temp = (char**) realloc(temp, sizeof(char*) * (n + 2)))
{
temp[n] = line;
temp[n+1] = NULL;
*page = temp;
}else printf("no memory\n");
}

int
main(void)
{
size_t i;
char *line;
char *line1 = "test1";
char *line2 = "test2";
char **page = init();
for(i=0;line=page[i];i++) printf("%s\n",line);
add(&page, line1, 0);
add(&page, line2, 1);
for(i=0;line=page[i];i++) printf("%s\n",line);
free(page);
}

Jul 16 '07 #25
gert <ge**********@gmail.comwrites:
On Jul 16, 6:54 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>You've had some very accurate and helpful answers, but just in case
there is an element "running before you can walk" here don't go any
further until you know what this program does and why:
<snip illustration of pass by value>
>>
Forgive me if this is too obvious, but you have this same error in
most of your postings.

--
Ben.
Please snip sigs.
i found the goodbye 43 solution :)

void inc(int *x)
{
*x = *x + 1;
}

void say_goodbye(char *s)
{
strcpy(s, "goodbye\n");
}

int main(void)
{
char *string = malloc(9);
int *i= malloc(sizeof(int));
*i=42;
inc(i);
say_goodbye(string);
printf("%s %d\n", string, *i);
return 0;
}
A detail: malloc is not needed.

char string[9];
int i = 42;
inc(&i);
say_goodbye(string);
printf("%s %d\n", string, *i);

but yes, you have the idea. I am sorry if that came over as
patronising. I intended it to be helpful!

--
Ben.
Jul 16 '07 #26
gert <ge**********@gmail.comwrites:
#BINGO RELEASE CANDIDATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char **
init(void)
{
char **p;
if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}
[snip]

Um, did you try running this before you posted it? The
'exit(EXIT_FAILURE)' call is executed unconditionally.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 16 '07 #27
On Jul 17, 1:11 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
A detail: malloc is not needed.

char string[9];
int i = 42;
inc(&i);
say_goodbye(string);
printf("%s %d\n", string, *i);

but yes, you have the idea. I am sorry if that came over as
patronising. I intended it to be helpful!
It was good practice, i didn't figure it out directly :) My programs
do have many problems and all do you people can predict the outcome i
just have to see it crash to know why :) So if there are 5 problems i
need to make it crash 5 times to figure it out by ignoring part of
your solutions.

Jul 16 '07 #28
On Jul 17, 1:31 am, Keith Thompson <ks...@mib.orgwrote:
gert <gert.cuyk...@gmail.comwrites:
#BINGO RELEASE CANDIDATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char **
init(void)
{
char **p;
if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}
Um, did you try running this before you posted it? The
'exit(EXIT_FAILURE)' call is executed unconditionally.
Yes it will not happen as long there is enough memory

Jul 16 '07 #29
Keith Thompson said:
gert <ge**********@gmail.comwrites:
<snip>
> if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}
[snip]

Um, did you try running this before you posted it?
Did you?
The 'exit(EXIT_FAILURE)' call is executed unconditionally.
Only if the malloc fails. Early returns do make code harder to read,
don't they?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 16 '07 #30
gert <ge**********@gmail.comwrites:
On Jul 17, 1:31 am, Keith Thompson <ks...@mib.orgwrote:
>gert <gert.cuyk...@gmail.comwrites:
#BINGO RELEASE CANDIDATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char **
init(void)
{
char **p;
if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}
Um, did you try running this before you posted it? The
'exit(EXIT_FAILURE)' call is executed unconditionally.

Yes it will not happen as long there is enough memory

Once of the consequences of the awful habit of not "correctly" indenting
lines is that its harder to debug properly or cleanly nor can you read the
code properly without extra effort.

static char ** init(void)
{
char **p;
if(p=malloc(sizeof(char*))){
p[0] = NULL;
return p;
}else{
printf("no memory\n");
}
exit(EXIT_FAILURE);
}
While "correctly" is open to many readings the K&R standard is widely
used and, IMO, one of the most pleasing on the eye in terms of "bracket
matching". But regardless of that:

The issue above is that you have the "else" and THEN the exit() call
outside of the "else" making it a little confusing. Yes, the else drops
into the return but, stylewise, IMO the following is cleaner:

static char ** init(void)
{
char **p;

if((p=malloc(sizeof(char*)))==NULL){
printf("no memory\n");
exit(EXIT_FAILURE);
}

p[0] = NULL;
return p;
}

or something :-)
Jul 17 '07 #31
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
>gert <ge**********@gmail.comwrites:
<snip>
>> if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}
[snip]

Um, did you try running this before you posted it?

Did you?
Um, no. I hang my head in shame. Apologies to the OP.
Only if the malloc fails. Early returns do make code harder to read,
don't they?
Alas, this probably won't teach me to stop using them myself.

I probably would have noticed the return statement if the code had
been formatted better (more white space, more than single-column
indentation). Not that that's any excuse for my mistake, of course.

Now that I'm actually taking a close look at the code, I don't
understand why the printf() is in the else clause, but the exit()
isn't.

Here's the original function:

static char **
init(void)
{
char **p;
if(p=malloc(sizeof(char*)))
{
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);
}

I *might* write it like this:

static char **init(void)
{
char **p;
if ((p = malloc(sizeof *p)) != NULL) {
p[0] = NULL;
return p;
}
fprintf(stderr, "no memory\n");
exit(EXIT_FAILURE);
}

but I'd more likely write it like this:

static char **init(void)
{
char **p;
if ((p = malloc(sizeof *p)) != NULL) {
p[0] = NULL;
return p;
}
else {
fprintf(stderr, "no memory\n");
exit(EXIT_FAILURE);
}
}

(I also replaced 'sizeof(char*)' with 'sizeof *p', printed the error
message to stderr rather than stdout, and avoided using the result of
an assignment as a condition.)

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 17 '07 #32
lol well you never going to believe how i think when i write code

I start making code in lala land where everything works like it should
be

char **p;
p = malloc(sizeof *p) //*p is indeed nicer then (char*)
p[0] = NULL;
return p;

Then you guys tell me check your memory allocation
I go like blablabla ok then

char **p;
if(p=malloc(sizeof *p)){
p[0] = NULL;
return p;
}else printf("no memory\n");

Here i am turning around on my chair while my brains are debugging the
code while suddenly they say "Wait a minute!" what if memory fails and
i start printing line's when there is no NULL pointer.... DOH!!!

char **p;
if(p=malloc(sizeof *p)){
p[0] = NULL;
return p;
}else printf("no memory\n");
exit(EXIT_FAILURE);

Well then, nicely done!

You see my code is actually nothing more then a stack dump of how my
mind works :)

Jul 17 '07 #33
gert wrote:
Aha so char *page[]={NULL}; needs to be replaced with some malloc
first.
Back to drawing board.
What is unclear about :
realloc() changes the size of the memory block pointed to by ptr to
size bytes. The contents will be unchanged to the minimum of
the old
and new sizes; newly allocated memory will be uninitialized. If
ptr is
NULL, the call is equivalent to malloc(size); if size is equal
to zero,
the call is equivalent to free(ptr). Unless ptr is NULL, it
must have
been returned by an earlier call to malloc(), calloc() or
realloc().
If the area pointed to was moved, a free(ptr) is done.

? You also might want to try Valgrind, not all malloc() implementations
report errors like this.

Igmar
Jul 17 '07 #34
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
<snip>
>Early returns do make code harder to read, don't they?

Alas, this probably won't teach me to stop using them myself.
Even when they're not necessary?

<snip>
but I'd more likely write it like this:

static char **init(void)
{
char **p;
if ((p = malloc(sizeof *p)) != NULL) {
p[0] = NULL;
return p;
}
else {
fprintf(stderr, "no memory\n");
exit(EXIT_FAILURE);
}
}

(I also replaced 'sizeof(char*)' with 'sizeof *p', printed the error
message to stderr rather than stdout, and avoided using the result of
an assignment as a condition.)
If put the responsibility for deciding whether we can recover from the
allocation failure where it belongs (i.e. in the caller), then the
function becomes much simpler:

#include <stdlib.h>

static char **init(void)
{
char **p = malloc(sizeof *p);
if(p != NULL)
{
p[0] = NULL;
}
return p;
}

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 17 '07 #35
On Jul 17, 10:57 am, mark_blue...@pobox.com wrote:
If I come back to this code in 6 months or a year, I'll know what it
does and how. Is that true of your design?
No, but i can recall all the mistakes i made :) So for me this code is
perfectly for learning, I read it like, ok then i do that then i do
this , but why i did that ? A yes because of the print thingie.
Consider it as a library of mistakes. But i do admit its not the way
you make real programs.

Jul 17 '07 #36
I still don't believe this modified bingo code actually works without
posting 45 messages first :)

http://dfo.svn.sourceforge.net/viewv...80&view=markup
Jul 18 '07 #37

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

32 posts views Thread by Clunixchit | last post: by
2 posts views Thread by akhilesh.noida | last post: by
reply views Thread by rosydwin | last post: by

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.