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

Segmentation fault!

P: n/a
I have a wierd problem.

In my main function I print "test" as the first thing. But if I run the call
to node_alloc AFTER the printf call I get a segmentation fault and test is
not printed!

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

typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t));
parent->content = content;
parent->num_kids = num;
node_t *new_kids[num];
int i;

// Initialize children to NULL.
for (i = 0; i < num; i++)
{
parent->kids[i]=NULL;

}
return parent;
}
int main(void)
{

printf("test");
node_t *root = node_alloc("Root",4);
return 0;
}
Only if I outcomment the call to node_alloc will it print "test"! Why does
it not print "test" and then afterwards give me the "Segmentation Fault"?

It seems that the call to node_alloc is executed before the printf call...
Feb 11 '06 #1
Share this Question
Share on Google+
27 Replies


P: n/a
Paminu wrote:
I have a wierd problem.

In my main function I print "test" as the first thing. But if I run
the call to node_alloc AFTER the printf call I get a segmentation
fault and test is not printed!

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

typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t));
You should test whether malloc() returns NULL.
parent->content = content;
parent->num_kids = num;
node_t *new_kids[num];
int i;
You're missing this line:

parent->kids = new_kids;

But then, you'd really want:

parent->kids = malloc(num * sizeof (node_t *));
if (parent->kids) ...

As `new_kids` will disappear after you exit the function.

// Initialize children to NULL.
for (i = 0; i < num; i++)
{
parent->kids[i]=NULL;

}
return parent;
}
int main(void)
{

printf("test");
If you don't terminate printf() with \n you may not get anything out.
node_t *root = node_alloc("Root",4);
return 0;
}
Only if I outcomment the call to node_alloc will it print "test"! Why
does it not print "test" and then afterwards give me the "Segmentation
Fault"?

It seems that the call to node_alloc is executed before the printf
call...


No, you just invoked the wrath of Undefined Behaviour, by trying to
access uninitialised pointers...

--
BR, Vladimir

What!? Me worry?
-- A.E. Newman

Feb 11 '06 #2

P: n/a

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
I have a wierd problem.

In my main function I print "test" as the first thing. But if I run the call to node_alloc AFTER the printf call I get a segmentation fault and test is
not printed!

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

typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t));
parent->content = content;
parent->num_kids = num;
node_t *new_kids[num];
int i;

// Initialize children to NULL.
for (i = 0; i < num; i++)
{
parent->kids[i]=NULL;

}
return parent;
}
int main(void)
{

printf("test");
node_t *root = node_alloc("Root",4);
return 0;
}
Only if I outcomment the call to node_alloc will it print "test"! Why does
it not print "test" and then afterwards give me the "Segmentation Fault"?

It seems that the call to node_alloc is executed before the printf call...


No, node_alloc() is executed after the printf() call. Since you didn't
fflush() stdout or use a newline, '\n', with printf(), the output from print
isn't displayed until your program exits. At which point, stdio is flushed
by either exit() or return(), thereby, displaying test. The "Segmentation
Fault" is probably the result of not allocating space for the data
'parent->content' points to. Since you are wanting to use pointers for
'parent->content', it is probably best to add another malloc() allocate
space for the data at 'content' and then use strcpy() to copy the data to
the newly malloc()'d memory.

I'm sorry to say, but this exact situation has been covered in probably ten
or fifteen different threads here over the past month with different degrees
of eloquence.
Rod Pemberton

Feb 11 '06 #3

P: n/a
>> It seems that the call to node_alloc is executed before the printf
call...


No, you just invoked the wrath of Undefined Behaviour, by trying to
access uninitialised pointers...

Ok so the reason is that I have not initialized the pointer to the pointer.

If I have this struct:

typedef struct _node_t {
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

I can now initialize a pointer to this struct (I know that I should use
malloc if I want to use the result outside the function):

1)
node_t *np;
np = NULL; // INITIALIZE A POINTER TO NULL

This compiles and when I run it I get no segmentation fault.

Why is this different from initializing the pointer to the pointer in the
struct by:

2)
node_t *np;
np=malloc(sizeof(node_t));
np->content = "test";
np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL
In the last line "np->kids[0]" is a pointer to node_t which is allowed to
point to NULL. I compiles fine but when I run it I get a segmentation
fault. I can't see the difference between 1) and 2).


Feb 11 '06 #4

P: n/a

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
Ok so the reason is that I have not initialized the pointer to the pointer.
If I have this struct:

typedef struct _node_t {
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

I can now initialize a pointer to this struct (I know that I should use
malloc if I want to use the result outside the function):

1)
node_t *np;
np = NULL; // INITIALIZE A POINTER TO NULL

This compiles and when I run it I get no segmentation fault.

Why is this different from initializing the pointer to the pointer in the
struct by:

2)
node_t *np;
np=malloc(sizeof(node_t));
np->content = "test";
np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL
Maybe because you did not allocate any space for np->kids itself?
In the last line "np->kids[0]" is a pointer to node_t which is allowed to
point to NULL. I compiles fine but when I run it I get a segmentation
fault. I can't see the difference between 1) and 2).

Feb 11 '06 #5

P: n/a
stathis gotsis wrote:

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
Ok so the reason is that I have not initialized the pointer to the

pointer.

If I have this struct:

typedef struct _node_t {
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

I can now initialize a pointer to this struct (I know that I should use
malloc if I want to use the result outside the function):

1)
node_t *np;
np = NULL; // INITIALIZE A POINTER TO NULL

This compiles and when I run it I get no segmentation fault.

Why is this different from initializing the pointer to the pointer in the
struct by:

2)
node_t *np;
np=malloc(sizeof(node_t));
np->content = "test";
np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL


Maybe because you did not allocate any space for np->kids itself?

I did not do that i 1) either and it worked
Feb 11 '06 #6

P: n/a

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
stathis gotsis wrote:

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
Ok so the reason is that I have not initialized the pointer to the

pointer.

If I have this struct:

typedef struct _node_t {
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

I can now initialize a pointer to this struct (I know that I should use
malloc if I want to use the result outside the function):

1)
node_t *np;
np = NULL; // INITIALIZE A POINTER TO NULL

This compiles and when I run it I get no segmentation fault.

Why is this different from initializing the pointer to the pointer in the struct by:

2)
node_t *np;
np=malloc(sizeof(node_t));
np->content = "test";
np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL


Maybe because you did not allocate any space for np->kids itself?

I did not do that i 1) either and it worked


I think you meant to write

np->kids = NULL;

rather than

np->kids[0] = NULL;

--
RSH

Feb 11 '06 #7

P: n/a
Robin Haigh wrote:

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
stathis gotsis wrote:
>
> "Paminu" <sd**@asd.com> wrote in message
> news:ds**********@news.net.uni-c.dk...
>> Ok so the reason is that I have not initialized the pointer to the
> pointer.
>>
>> If I have this struct:
>>
>> typedef struct _node_t {
>> void *content;
>> struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
>> } node_t;
>>
>> I can now initialize a pointer to this struct (I know that I should
>> use malloc if I want to use the result outside the function):
>>
>> 1)
>> node_t *np;
>> np = NULL; // INITIALIZE A POINTER TO NULL
>>
>> This compiles and when I run it I get no segmentation fault.
>>
>>
>>
>> Why is this different from initializing the pointer to the pointer in the >> struct by:
>>
>> 2)
>> node_t *np;
>> np=malloc(sizeof(node_t));
>> np->content = "test";
>> np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL
>
> Maybe because you did not allocate any space for np->kids itself?

I did not do that i 1) either and it worked


I think you meant to write

np->kids = NULL;

rather than

np->kids[0] = NULL;

No I actually meant "np->kids[0] = NULL" which is precisly what I cannot
understand gives an error.

"np->kids[0]" is a pointer to node_t and it is therefore legal to initialize
it to NULL.

But when I run the program I get a segmentation fault. A solution for this
problem is as mentioned to write: np->kids=malloc(sizeof(node_t*)). Then it
runs without error. But I don't understand why.
If I have:

int main(void)
{
int **ip;
ip[2] = NULL;
return 0;
}

this compiles and runs fine without first using malloc (and I am aware that
omitting malloc removes the declarations after the function returns).
Feb 11 '06 #8

P: n/a

"Vladimir S. Oka" <no****@btopenworld.com> wrote in message
news:ds**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
Paminu wrote:
I have a wierd problem.

In my main function I print "test" as the first thing. But if I run
the call to node_alloc AFTER the printf call I get a segmentation
fault and test is not printed!

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

typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;
*** kids is an array of pointers to _node_t, correct? Wouldn't kids be
better defined like so:
struct _node_t *(kids[]);
node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t));
You should test whether malloc() returns NULL.
parent->content = content;
parent->num_kids = num;
node_t *new_kids[num];
int i;


*** He's changing the type of content from 'const char *' to 'void *'.
Also, if he doesn't allocate space for content, he'll continue to get
segmentation faults.
You're missing this line:

parent->kids = new_kids;

But then, you'd really want:

parent->kids = malloc(num * sizeof (node_t *));
if (parent->kids) ...

As `new_kids` will disappear after you exit the function.

// Initialize children to NULL.
for (i = 0; i < num; i++)
{
parent->kids[i]=NULL;

}
return parent;
}
int main(void)
{

printf("test");


If you don't terminate printf() with \n you may not get anything out.
node_t *root = node_alloc("Root",4);
return 0;
}


I think his program should look more like this:

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

typedef struct _node_t
{
int num_kids;
char *content;
struct _node_t *(kids[]);
} node_t;

void node_alloc(node_t *parent, char *content, int num)
{
int i;

parent = malloc(sizeof(node_t));
parent->num_kids = num;
parent->content = malloc(strlen(content));
strcpy(parent->content,content);
parent->kids[0] = malloc(sizeof(node_t *)*num);

// Initialize children to NULL.
for(i=0;i<num;i++)
parent->kids[i]=NULL;
}
int main(void)
{
node_t *root=NULL,*next=NULL;
char temp[32];

printf("test\n");
sprintf(temp,"%s","Root");
node_alloc(root,temp,4);
sprintf(temp,"%s","First");
node_alloc(next,temp,3);
root->kids[0]=next;
sprintf(temp,"%s","Second");
node_alloc(next,temp,2);
root->kids[1]=next;
return 0;
}
Rod Pemberton
Feb 11 '06 #9

P: n/a
"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
Robin Haigh wrote:

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
stathis gotsis wrote:

>
> "Paminu" <sd**@asd.com> wrote in message
> news:ds**********@news.net.uni-c.dk...
>> Ok so the reason is that I have not initialized the pointer to the
> pointer.
>>
>> If I have this struct:
>>
>> typedef struct _node_t {
>> void *content;
>> struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
>> } node_t;
>>
>> I can now initialize a pointer to this struct (I know that I should
>> use malloc if I want to use the result outside the function):
>>
>> 1)
>> node_t *np;
>> np = NULL; // INITIALIZE A POINTER TO NULL
>>
>> This compiles and when I run it I get no segmentation fault.
>>
>>
>>
>> Why is this different from initializing the pointer to the pointer
in the
>> struct by:
>>
>> 2)
>> node_t *np;
>> np=malloc(sizeof(node_t));
>> np->content = "test";
>> np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL
>
> Maybe because you did not allocate any space for np->kids itself?
I did not do that i 1) either and it worked
I think you meant to write

np->kids = NULL;

rather than

np->kids[0] = NULL;

No I actually meant "np->kids[0] = NULL" which is precisly what I cannot
understand gives an error.

"np->kids[0]" is a pointer to node_t and it is therefore legal to

initialize it to NULL.

But when I run the program I get a segmentation fault. A solution for this
problem is as mentioned to write: np->kids=malloc(sizeof(node_t*)). Then it runs without error. But I don't understand why.


You are initialising np->kids[0] the first element of an array of pointers,
but you did not allocate any space for the array itself. It is similar to:
int *a;
a[0]=1;
Feb 11 '06 #10

P: n/a

"stathis gotsis" <st***********@hotmail.com> wrote in message
news:ds***********@ulysses.noc.ntua.gr...
You are initialising np->kids[0] the first element of an array of pointers, but you did not allocate any space for the array itself. It is similar to:
int *a;
a[0]=1;


That is not the correct way to express it because there are no arrays here
actually, but i hope you can see my point.
Feb 11 '06 #11

P: n/a
>> Paminu wrote:
[snippage]
typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;
Since no one else has mentioned it yet, it is wise to avoid leading
underscores on names (unless you are the guy writing the compiler
in the first place, in which case it is wise to prefer leading
underscores on names -- the goal here is to keep the programmer's
names, which never start with underscore, from accidentally colliding
with the implementor's names, which always start with underscore).
It is also best to write the typedefs *before* defining the
structures, if you are going to use typedefs at all, because --
well, you will see in a moment:

typedef struct node_t node_t; /* this comes first ... */

struct node_t {
int num_kids;
void *content;
node_t **kids; /* ... because then you can use it here! */
};

(My own preferred method is to omit the "typedef" entirely, and
just write out "struct" as needed.)

In any case, avoid the leading underscore -- the implementor is
using those names!

In article <43********@news.bea.com>
Rod Pemberton <do*********@sorry.bitbucket.cmm> wrote:

(Hm, which one is it, ".cmm" or ".com"?)
*** kids is an array of pointers to _node_t, correct?
Well, "to be used as" -- as it stands, it is a pointer, which can
point to zero or more objects of type "pointer to struct _node_t".
("struct _node_t" is the real name, "node_t" is just an alias
that allows omitting the seven characters "struct ".)
Wouldn't kids be better defined like so:
struct _node_t *(kids[]);
This is a C99 feature: a structure that ends with a member of type
"array of T" (for some valid data type T), with no size, creates
a struct type with a "flexible array member". While C99-conformant
compilers are becoming more common, in my opinion they are not yet
common enough to recommend regular use of C99 features. Still,
this is a reasonable thing to do if you have C99 compilers. This
gives:

struct node_t {
int num_kids;
void *content;
node_t *kids[]; /* C99 flexible array member; must be last */
};

i.e., the parenthese are unnecessary. Using the flexible array
member will save one malloc() call.
node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t)); "Vladimir S. Oka" <no****@btopenworld.com> wrote in message
news:ds**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
You should test whether malloc() returns NULL.

Indeed.

Using the flexible array member method, you must add to the
size requested here. You will want enough storage for *parent
(a "node_t", so either "sizeof *parent" or "sizeof(node_t)" will
work) *plus* enough storage for "num" pointers to "node_t":

parent = malloc(sizeof *parent + num * sizeof *(parent->kids));
/*
* or, equivalently:
parent = malloc(sizeof(node_t) + num * sizeof(node_t *));
*
* Note that the parentheses around parent->kids are actually
* redundant, so you could write:
parent = malloc(sizeof *parent + num * sizeof *parent->kids);
*/
parent->content = content;
parent->num_kids = num;
These lines are fine.
node_t *new_kids[num];
This line also uses a C99 feature, or in fact, *two* C99 features:
"declaration anywhere" and "variable length array". This creates
an automatic-storage-duration array, "new_kids", of size "num", with
elements of type "pointer to struct node_t".

Because this array has automatic storage duration, it will vanish
when the function returns (as Vladimir Oka notes later).
int i;


And this also uses the C99 "declaration anywhere" feature.
*** He's changing the type of content from 'const char *' to 'void *'.


If all the quoting is accurate, this is not the case in the code
fragment shown, at least. The parameter to the function is "void *"
and the member named parent is "void *"; there are no "const char *"s
to be seen.

(I do not have access to the entire original code, only the parts
quoted in the article to which this is a followup.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Feb 11 '06 #12

P: n/a

"Chris Torek" <no****@torek.net> wrote in message
news:ds*********@news1.newsguy.com...
Rod Pemberton wrote:
Wouldn't kids be better defined like so:
struct _node_t *(kids[]);


This is a C99 feature: a structure that ends with a member of type
"array of T" (for some valid data type T), with no size, creates
a struct type with a "flexible array member". While C99-conformant
compilers are becoming more common, in my opinion they are not yet
common enough to recommend regular use of C99 features. Still,
this is a reasonable thing to do if you have C99 compilers. This
gives:


Just an FYI (for others, since Chris is probably familiar), this technique
existed prior to C99. It was called the C90 'struct hack' and works with
almost all C compilers. When standardized in C99, it became known as
variable length arrays.

If you've never heard of the C90 'struct hack', read #28 here:
http://home.tiscalinet.ch/t_wolf/tw/c/c9x_changes.html
Rod Pemberton
Feb 11 '06 #13

P: n/a
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> wrote in message
news:43********@news.bea.com...

"Vladimir S. Oka" <no****@btopenworld.com> wrote in message
news:ds**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
Paminu wrote:
I have a wierd problem.

In my main function I print "test" as the first thing. But if I run
the call to node_alloc AFTER the printf call I get a segmentation
fault and test is not printed!

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

typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;
*** kids is an array of pointers to _node_t, correct? Wouldn't kids be
better defined like so:
struct _node_t *(kids[]);
I think those parenthesis are not necessary, but i would stick to: struct
_node_t **kids;
node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t));


You should test whether malloc() returns NULL.
parent->content = content;
parent->num_kids = num;
node_t *new_kids[num];
int i;
*** He's changing the type of content from 'const char *' to 'void *'.
Also, if he doesn't allocate space for content, he'll continue to get
segmentation faults.


That (may) happen later on his code:
node_alloc("Root",4);

I think string litterals are not of type "const char[]" but of "char[]". The
OP may want parent->content to point to some "elsewhere" malloc'd memory,
what would be the problem with that? I think it is also alright if it
contains the address of a string litteral. Furthermore, the OP may want
parent->content to point to different types of data, not just char.
You're missing this line:

parent->kids = new_kids;

But then, you'd really want:

parent->kids = malloc(num * sizeof (node_t *));
if (parent->kids) ...

As `new_kids` will disappear after you exit the function.

// Initialize children to NULL.
for (i = 0; i < num; i++)
{
parent->kids[i]=NULL;

}
return parent;
}
int main(void)
{

printf("test");


If you don't terminate printf() with \n you may not get anything out.
node_t *root = node_alloc("Root",4);
return 0;
}


I think his program should look more like this:

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

typedef struct _node_t
{
int num_kids;
char *content;
struct _node_t *(kids[]);


I would use: struct _node_t **kids;
} node_t;

void node_alloc(node_t *parent, char *content, int num)
{
int i;

parent = malloc(sizeof(node_t));
parent->num_kids = num;
parent->content = malloc(strlen(content));
strcpy(parent->content,content);
I think this is: parent->content = malloc((strlen(content)+1)*sizeof(char));
parent->kids[0] = malloc(sizeof(node_t *)*num);
That is not correct, maybe you meant:
parent->kids=malloc(...). That works with "struct _node_t **kids;
// Initialize children to NULL.
for(i=0;i<num;i++)
parent->kids[i]=NULL;
}
int main(void)
{
node_t *root=NULL,*next=NULL;
char temp[32];

printf("test\n");
sprintf(temp,"%s","Root");
node_alloc(root,temp,4);
That call will not change root, you are passing it by value.
sprintf(temp,"%s","First");
node_alloc(next,temp,3);
root->kids[0]=next;
As a result, the previous statement could lead into trouble.
sprintf(temp,"%s","Second");
node_alloc(next,temp,2);
root->kids[1]=next;
return 0;
}


Malloc'd memory should be freed at some point.
Feb 11 '06 #14

P: n/a
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
[...]
Just an FYI (for others, since Chris is probably familiar), this technique
existed prior to C99. It was called the C90 'struct hack' and works with
almost all C compilers. When standardized in C99, it became known as
variable length arrays.


You're thinking of flexible array members; variable length arrays are
a different feature.

Rod, a personal observation: your recent postings here have actually
been reasonable. Have you decided not to be an abusive troll? (See
the recent "Which members are created automatically, which members are
not inherited?" thread if you don't know what I'm referring to.)

--
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.
Feb 11 '06 #15

P: n/a

"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...
If I have:

int main(void)
{
int **ip;
ip[2] = NULL;
return 0;
}

this compiles and runs fine


Not for me, but anyway. What about this?

#include <stdio.h>
int main(void)
{
int **ip;
int j;
ip[2] = NULL;
ip[100000] = NULL;
ip[46578483] = NULL;
for ( j = 0 ; j < 1000000 ; j++ ) {
ip[j] = NULL;
}
scanf("%d", &j);
ip[j] = NULL;
return 0;
}

Leaving aside the question of whether it actually works, do you think it
ought to work? If not, where are you drawing the line?

--
RSH

Feb 11 '06 #16

P: n/a

"stathis gotsis" <st***********@hotmail.com> wrote in message
news:ds***********@ulysses.noc.ntua.gr...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> wrote in message
news:43********@news.bea.com...

"Vladimir S. Oka" <no****@btopenworld.com> wrote in message
news:ds**********@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
Paminu wrote:

> I have a wierd problem.
>
> In my main function I print "test" as the first thing. But if I run
> the call to node_alloc AFTER the printf call I get a segmentation
> fault and test is not printed!
>
> #include <stdlib.h>
> #include <stdio.h>
>
> typedef struct _node_t {
> int num_kids;
> void *content;
> struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
> } node_t;
*** kids is an array of pointers to _node_t, correct? Wouldn't kids be
better defined like so:
struct _node_t *(kids[]);


I think those parenthesis are not necessary, but i would stick to: struct
_node_t **kids;
> node_t *node_alloc(void *content, int num)
> {
> node_t *parent;
> parent = malloc(sizeof(node_t));

You should test whether malloc() returns NULL.

> parent->content = content;
> parent->num_kids = num;
> node_t *new_kids[num];
> int i;


*** He's changing the type of content from 'const char *' to 'void *'.
Also, if he doesn't allocate space for content, he'll continue to get
segmentation faults.


That (may) happen later on his code:
node_alloc("Root",4);

I think string litterals are not of type "const char[]" but of "char[]".

The OP may want parent->content to point to some "elsewhere" malloc'd memory,
what would be the problem with that? I think it is also alright if it
contains the address of a string litteral. Furthermore, the OP may want
parent->content to point to different types of data, not just char.
You're missing this line:

parent->kids = new_kids;

But then, you'd really want:

parent->kids = malloc(num * sizeof (node_t *));
if (parent->kids) ...

As `new_kids` will disappear after you exit the function.

>
> // Initialize children to NULL.
> for (i = 0; i < num; i++)
> {
> parent->kids[i]=NULL;
>
> }
> return parent;
> }
>
>
> int main(void)
> {
>
> printf("test");

If you don't terminate printf() with \n you may not get anything out.

> node_t *root = node_alloc("Root",4);
> return 0;
> }
>
I think his program should look more like this:

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

typedef struct _node_t
{
int num_kids;
char *content;
struct _node_t *(kids[]);


I would use: struct _node_t **kids;
} node_t;

void node_alloc(node_t *parent, char *content, int num)
{
int i;

parent = malloc(sizeof(node_t));
parent->num_kids = num;
parent->content = malloc(strlen(content));
strcpy(parent->content,content);


I think this is: parent->content =

malloc((strlen(content)+1)*sizeof(char));
parent->kids[0] = malloc(sizeof(node_t *)*num);


That is not correct, maybe you meant:
parent->kids=malloc(...). That works with "struct _node_t **kids;
// Initialize children to NULL.
for(i=0;i<num;i++)
parent->kids[i]=NULL;
}
int main(void)
{
node_t *root=NULL,*next=NULL;
char temp[32];

printf("test\n");
sprintf(temp,"%s","Root");
node_alloc(root,temp,4);


That call will not change root, you are passing it by value.
sprintf(temp,"%s","First");
node_alloc(next,temp,3);
root->kids[0]=next;


As a result, the previous statement could lead into trouble.
sprintf(temp,"%s","Second");
node_alloc(next,temp,2);
root->kids[1]=next;
return 0;
}


Malloc'd memory should be freed at some point.

I must admit. That was a superb call on all errors. Written in haste, what
a waste...

Rod Pemberton
Feb 11 '06 #17

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
[...]
Rod, a personal observation: your recent postings here have actually
been reasonable.
My posts were reasonable in the beginning too, until 'off topic' abuse
killed every conversation here. You and a supportive group of cronies were
a prime factor in this.
Have you decided not to be an abusive troll?
Reasons: A to K.

A) Time constraints, I can't post to everything, 24 hours a day, like some
people.
B) Others, who exhibited troll like behavior, have slowed their non-relevant
posts.
C) A number of people who hadn't been posting started posting after
recognizing valid C questions buried beneath 'off topic' C questions.
D) I'm ignoring Mark McIntyre, since I don't 'get' his perspective AND he
seems uninterested in C.
E) I'm laughing heavily _with_ Kenny McCormack, although he doesn't
contribute to C conversation either. His humor reduces the sharpness of
some people's comments.
F) You haven't read some of the junk threads.
G) The poster of the 'mental abuse' thread was a 'dead ringer' for a cousin
who is clinically schizoid and refuses medication. The exception being, he
usually also discusses flying dragons. It was then, I realized you might
not be so off...
H) You went on a two and half day temper tantrum, posting to every thread in
sight, and are now down to two troll-ish "off topic" comments per day. Keep
it up, er, I mean down.
I) Being a self-proclaimed C god, I wanted to see if you'd post anything of
interest to P.J.Plauger or Doug Gwyn. You didn't. You could have asked
them about anything...
J) This post, to one of the fork() threads, never made it: I noticed you didn't tell P.J. Plauger in the "fork implementation"
thread that he was off topic... Why is that? Double standard,
perhaps? You defer to "authority," but expect others to defer
to your "authority"...

K) I remembered there are many Thompson's in my Mother's side of the
family... (I'm not joking.)
Rod Pemberton
Feb 12 '06 #18

P: n/a
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
[...]
Rod, a personal observation: your recent postings here have actually
been reasonable.


My posts were reasonable in the beginning too, until 'off topic' abuse
killed every conversation here. You and a supportive group of cronies were
a prime factor in this.
Have you decided not to be an abusive troll?


Reasons: A to K.


[snip]

In other words, no.

Bye.

--
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.
Feb 12 '06 #19

P: n/a
Keith Thompson <ks***@mib.org> writes:
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
[...]
Rod, a personal observation: your recent postings here have actually
been reasonable.


My posts were reasonable in the beginning too, until 'off topic' abuse
killed every conversation here. You and a supportive group of cronies were
a prime factor in this.
Have you decided not to be an abusive troll?


Reasons: A to K.


[snip]

In other words, no.

Bye.


That was probably just a little bit too harsh.

You did make *some* valid points in your A to K list.

I care about this newsgroup. You've made some useful contributions to
it, but you have also behaved in a distinctly trollish manner. You
came into a newsgroup that's been working quite well for many years
and loudly insisted that you're right and we're all wrong about how it
should be run. You have also cooperated with Kenny McCormack, who
does *nothing* but deliberately disrupt it. And you have repeatedly
insulted me personally, and I do not choose to ignore that.

That's why you're in the killfiles of a number of the regulars, and
it's why I don't intend to spend any more of my time communicating
with you. I don't choose to use a killfile myself; if I did, you'd be
in it. Because I have *some* respect for you, I wanted you to
understand that.

--
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.
Feb 12 '06 #20

P: n/a
Paminu wrote:
1)
node_t *np;
This line allocates 4 bytes (or whatever) of memory, gives it a
type "node_t *" gives it a name "np".
np = NULL; // INITIALIZE A POINTER TO NULL
This line makes that pointer point somewhere (or nowhere,
if you like).
2)
node_t *np;
np=malloc(sizeof(node_t));
np->kids[0] = NULL; // INITIALIZE A POINTER TO NULL

In the last line "np->kids[0]" is a pointer to node_t which is allowed to
point to NULL. I compiles fine but when I run it I get a segmentation
fault. I can't see the difference between 1) and 2).


'np->kids' is a pointer which is currently pointing to random memory,
since you have not initialized it to anything. When you write

np->kids[0]

you are de-referencing a random pointer so of course you get garbage
results. Regardless of whether you then try to assign a value to it
or not.

As someone else pointed out, this is much like writing:

int **p;
p[0] = NULL;

which is obviously an error.

Feb 12 '06 #21

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Keith Thompson <ks***@mib.org> writes:
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
[...]
Rod, a personal observation: your recent postings here have actually
been reasonable.

My posts were reasonable in the beginning too, until 'off topic' abuse
killed every conversation here. You and a supportive group of cronies were a prime factor in this.

Have you decided not to be an abusive troll?

Reasons: A to K.
[snip]

In other words, no.

Bye.


That was probably just a little bit too harsh.

You did make *some* valid points in your A to K list.

I care about this newsgroup.


You rarely help newbs, declaring everything OT. How is that caring?
You've made some useful contributions to
it, but you have also behaved in a distinctly trollish manner.
IMHO, you too.
You
came into a newsgroup that's been working quite well for many years
and loudly insisted that you're right and we're all wrong about how it
should be run.
You and others, scared off alot of guys who posted. There are 10-15 threads
like that still on the newservers I use. Now, alot of guys who afraid and
just sitting on the sidelines post. I'd say that is a major improvement.
I'm sorry you don't like the new format.
You have also cooperated with Kenny McCormack, who
does *nothing* but deliberately disrupt it.
Perhaps. IMO, his humor is on the mark. And, he usually only interjects
when other people are being assholes and bastards.
And you have repeatedly
insulted me personally, and I do not choose to ignore that.
Yes I did. I thought you needed a loud wake up call to get through your
complacent perspective.
That's why you're in the killfiles of a number of the regulars, and
it's why I don't intend to spend any more of my time communicating
with you.
If by regulars you mean, CBFalconer, Flash Gordon, Mark McIntyre, et.al. I
don't need their help. I don't need my time wasted by their posts. And, if
I'm in their 'killfiles', or OE or Mozilla filter, that's great, because
they won't be harassing me.
I don't choose to use a killfile myself; if I did, you'd be
in it. Because I have *some* respect for you, I wanted you to
understand that.


I read everything. I'm sure your skills are probably much better than I
previously proclaimed. And, I was recently made aware that some of mine are
a bit rusty.
Rod Pemberton
Feb 12 '06 #22

P: n/a
Robin Haigh wrote:
"Paminu" <sd**@asd.com> wrote in message
news:ds**********@news.net.uni-c.dk...

If I have:

int main(void)
{
int **ip;
ip[2] = NULL;
return 0;
}

this compiles and runs fine

Not for me, but anyway. What about this?

#include <stdio.h>
int main(void)
{
int **ip;
int j;
ip[2] = NULL;
ip[100000] = NULL;
ip[46578483] = NULL;
for ( j = 0 ; j < 1000000 ; j++ ) {
ip[j] = NULL;
}
scanf("%d", &j);
ip[j] = NULL;
return 0;
}

Leaving aside the question of whether it actually works, do you think it
ought to work? If not, where are you drawing the line?

You're both wrong.

int **ip;

This defines ip but does not initialize it. It doesn't point to anything
and there are no arrays in sight.

ip[2] = NULL;

and everything after it is nonsense.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Feb 12 '06 #23

P: n/a

"Joe Wright" <jo********@comcast.net> wrote in message
news:8M******************************@comcast.com. ..
Robin Haigh wrote:
What about this?

#include <stdio.h>
int main(void)
{
int **ip;
int j;
ip[2] = NULL;
ip[100000] = NULL;
ip[46578483] = NULL;
for ( j = 0 ; j < 1000000 ; j++ ) {
ip[j] = NULL;
}
scanf("%d", &j);
ip[j] = NULL;
return 0;
}

Leaving aside the question of whether it actually works, do you think it
ought to work? If not, where are you drawing the line?

You're both wrong.


Yes, that was supposed to be wrong. The poster tried to make a point by
presenting a wrong program.
Feb 12 '06 #24

P: n/a
On Sat, 11 Feb 2006 14:30:59 +0100, Paminu <sd**@asd.com> wrote:
I have a wierd problem.

In my main function I print "test" as the first thing. But if I run the call
to node_alloc AFTER the printf call I get a segmentation fault and test is
not printed!
The absence of output is a side effect of a poor call to printf. The
segmentation fault is the result of undefined behavior. The two
problem are unrelated.

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

typedef struct _node_t {
int num_kids;
void *content;
struct _node_t **kids; // Makes a pointer to a pointer of node_ts.
} node_t;

node_t *node_alloc(void *content, int num)
{
node_t *parent;
parent = malloc(sizeof(node_t));
You should check for malloc failures here. If it did fail (even
though unlikely), the rest of your code would invoke undefined
behavior.
parent->content = content;
parent->num_kids = num;
node_t *new_kids[num];
Many of our compilers still enforce the C89 requirement that
definitions precede executable statements. Get in the habit of
putting your definitions and declarations at the beginning of the
block. It will allow more people to help you.
int i;

// Initialize children to NULL.
for (i = 0; i < num; i++)
{
parent->kids[i]=NULL;
Here is where you invoke undefined behavior. parent points to an area
of memory that you allocated. That area is not initialized by malloc.
You are using the area to hold a node_t. You initialize some members
of the structure but not kids. Therefore the value of this pointer is
indeterminate. In the practical sense, it is unlikely to point to any
valid memory you own.

Attempting to evaluate this value invokes undefined behavior.
Even though it is not likely to cause a segmentation fault on most
home systems, it is still to be avoided because there is no recovery
once you invoke undefined behavior.

HOWEVER, attempting to dereference this value will (if you are
lucky) cause some type of run time failure like a segmentation fault.
Since kids is a pointer to pointer to struct, kids[i] is, by
definition, the i-th pointer to struct that kids points to. Since
kids was never initialized, it doesn't point anywhere meaningful.
Attempting to store a value (NULL in this case) into an object
(kids[i] in this case) which you have never defined or allocated is
always a bad idea.

}
return parent;
}
int main(void)
{

printf("test");
The absence of a \n in the format string or a subsequent call to
fflush allows your output to remain in the buffer until some other
event forces it to your screen.
node_t *root = node_alloc("Root",4);
return 0;
}
Only if I outcomment the call to node_alloc will it print "test"! Why does
it not print "test" and then afterwards give me the "Segmentation Fault"?
The output probably appears on your screen as a result of main
returning to your OS through your C run time startup and terminate
processes. When you have the segmentation fault, the OS takes control
immediately and kills your task.

It seems that the call to node_alloc is executed before the printf call...


Bad code produces misleading appearances.
Remove del for email
Feb 12 '06 #25

P: n/a
On Sat, 11 Feb 2006 20:01:53 -0500, in comp.lang.c , "Rod Pemberton"
<do*********@sorry.bitbucket.cmm> wrote:

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> writes:
[...]
Rod, a personal observation: your recent postings here have actually
been reasonable.


My posts were reasonable in the beginning too,


Please don't start again. Perhaps your words were polite, but your
posts were not either reasonable or polite. If you find that still
offends you, feel free to post elsewhere.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Feb 13 '06 #26

P: n/a
On Sat, 11 Feb 2006 21:57:04 -0500, in comp.lang.c , "Rod Pemberton"
<do*********@sorry.bitbucket.cmm> wrote:

(Keith wrote)
I care about this newsgroup.


You rarely help newbs, declaring everything OT. How is that caring?


Thats beyond all resaonableness. You are now into offensive fuckwit
territory.
You've made some useful contributions to
it, but you have also behaved in a distinctly trollish manner.


IMHO, you too.


You have absolutely no idea what you are talking about. I stronfgly
suspect that your posts have annoyed and antagonised most of the
regulars here, many of whom are probably no longer even reading your
nonsense. Thats your loss.

*plonk*
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Feb 13 '06 #27

P: n/a
In article <tc********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.net> wrote:
....
Thats beyond all resaonableness. You are now into offensive fuckwit
territory.


Get a grip, fella! Rod has already stated that he doesn't "get" your
position (And believe me, he's just being nice, saying it that way), so
I think you should assume that you are in his killfile.

And thus wasting your breath breathing fire as you normally do...

Feb 13 '06 #28

This discussion thread is closed

Replies have been disabled for this discussion.