Question to malloc

T

Thomas Barth

Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space.


function with recursion...
char *szFile = NULL,
....
while((ptrDirentry = readdir(ptrDir)) != NULL) {

if (strcmp((*ptrDirentry).d_name, ".") != 0 &&
strcmp((*ptrDirentry).d_name, "..") != 0) {

setAbsoluteFilename(szFile, szDir, (*ptrDirentry).d_name);
....


void setAbsoluteFilename(char *szFile, char *szDir, char *szFilename) {
int iLenF = strlen(szFilename),
iLenD = strlen(szDir);

szFile = (char *)malloc(1); //???
//szFile = (char *)malloc((iLenD + iLenF + 1));

strcat(szFile, szDir);
strcat(szFile, "/");
strcat(szFile, szFilename);

//sprintf(szFile, "%s/%s", szDir, szFilename);

printf("Filename: %s, Size: %d\n", szFile, strlen(szFile));

}

Why is it possible to assign strings to szFile bigger than space is
allocated?

Regards,
T h o m a s B
 
E

Eric Sosman

Thomas said:
Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space.

char *szFile = NULL,
...
szFile = (char *)malloc(1); //???
//szFile = (char *)malloc((iLenD + iLenF + 1));

strcat(szFile, szDir);
strcat(szFile, "/");
strcat(szFile, szFilename);

Why is it possible to assign strings to szFile bigger than space is
allocated?

Because undefined behavior is "undefined." There is
no guarantee that U.B. will cause a crash or other obvious
error. It may cause a subtle error that won't be found
until the most embarrassing moment possible. There's even
a chance that U.B. will turn out to be what you wanted --
not something to bank on, obviously ...
 
P

pemo

Thomas said:
Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value
to szFile because of missing space.


function with recursion...
char *szFile = NULL,
...
while((ptrDirentry = readdir(ptrDir)) != NULL) {

if (strcmp((*ptrDirentry).d_name, ".") != 0 &&
strcmp((*ptrDirentry).d_name, "..") != 0) {

setAbsoluteFilename(szFile, szDir, (*ptrDirentry).d_name);
...


void setAbsoluteFilename(char *szFile, char *szDir, char *szFilename)
{ int iLenF = strlen(szFilename),
iLenD = strlen(szDir);

szFile = (char *)malloc(1); //???
//szFile = (char *)malloc((iLenD + iLenF + 1));

strcat(szFile, szDir);
strcat(szFile, "/");
strcat(szFile, szFilename);

//sprintf(szFile, "%s/%s", szDir, szFilename);

printf("Filename: %s, Size: %d\n", szFile, strlen(szFile));

}

Why is it possible to assign strings to szFile bigger than space is
allocated?


Because C assumes you know what you're doing, and makes no assumption as to
the storage that szFile points to - you might own that memory through some
devious route ... e.g., perhaps you rewrote malloc(), and know what's after
szFile[0]!
 
P

pete

Thomas said:
Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space.

function with recursion...
char *szFile = NULL,
...
while((ptrDirentry = readdir(ptrDir)) != NULL) {

if (strcmp((*ptrDirentry).d_name, ".") != 0 &&
strcmp((*ptrDirentry).d_name, "..") != 0) {

setAbsoluteFilename(szFile, szDir, (*ptrDirentry).d_name);
...

void setAbsoluteFilename(char *szFile, char *szDir, char *szFilename) {
int iLenF = strlen(szFilename),
iLenD = strlen(szDir);

szFile = (char *)malloc(1); //???
//szFile = (char *)malloc((iLenD + iLenF + 1));

strcat(szFile, szDir);
strcat(szFile, "/");
strcat(szFile, szFilename);

//sprintf(szFile, "%s/%s", szDir, szFilename);

printf("Filename: %s, Size: %d\n", szFile, strlen(szFile));

}

/* BEGIN Absolute.c output */

Filename: MyDirectory/MyFile
Length: 18

/* END Absolute.c output */


/* BEGIN Absolute.c */

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

char *setAbsoluteFilename(char *szDir, char *szFilename);

int main(void)
{
char *szFile;

puts("\n/* BEGIN Absolute.c output */\n");
szFile = setAbsoluteFilename("MyDirectory", "MyFile");
if (szFile != NULL) {
printf("Filename: %s\nLength: %d\n", szFile, strlen(szFile));
free(szFile);
} else {
puts("szFile == NULL");
}
puts("\n/* END Absolute.c output */");
return 0;
}

char *setAbsoluteFilename(char *szDir, char *szFilename)
{
size_t iLenF;
size_t iLenD;
char *szFile;

iLenF = strlen(szFilename);
iLenD = strlen(szDir);
szFile = malloc(iLenD + 1 + iLenF + 1);
if (szFile != NULL) {
sprintf(szFile, "%s/%s", szDir, szFilename);
}
return szFile;
}

/* END Absolute.c */
 
R

Richard G. Riley

Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space.


function with recursion...
char *szFile = NULL,
...
while((ptrDirentry = readdir(ptrDir)) != NULL) {

if (strcmp((*ptrDirentry).d_name, ".") != 0 &&
strcmp((*ptrDirentry).d_name, "..") != 0) {

setAbsoluteFilename(szFile, szDir, (*ptrDirentry).d_name);
...


void setAbsoluteFilename(char *szFile, char *szDir, char *szFilename) {
int iLenF = strlen(szFilename),
iLenD = strlen(szDir);

szFile = (char *)malloc(1); //???
//szFile = (char *)malloc((iLenD + iLenF + 1));

strcat(szFile, szDir);
strcat(szFile, "/");
strcat(szFile, szFilename);

//sprintf(szFile, "%s/%s", szDir, szFilename);

printf("Filename: %s, Size: %d\n", szFile, strlen(szFile));

}

Why is it possible to assign strings to szFile bigger than space is
allocated?

Regards,
T h o m a s B

One of the things to keep in mind that HW Segmentation doesnt run to
that level. You basically have a big block of memory. C assumes you
take care of certain things like buffer over runs : it is one of the
reasons it is so efficient : you need to keep tabs of this yourself.

Use the memory inspection utiltiy of your debugger and you will almost
certainly see other variables being overwritten. its worth the time to
investigate as you will become far more confident in using pointers
and blocks of memory.
 
D

Default User

Thomas said:
Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value
to szFile because of missing space.

It may sound like a tautology, but there is no defined behavior for
Undefined Behavior. So you can NOT have any expectations.

Don't do it.



Brian
 
C

CBFalconer

Thomas said:
I would like to create a file index like updatedb on Linux does
as a part of my program, but I dont know how long the filenames
could be. Therefore I want to use malloc to keep the size of the
filenames flexible. I would expect an segmentation fault with
the following sourcecode, when invoking strcat or sprintf to
assign the first value to szFile because of missing space.
.... snip ...
From the description of stdio.h in N869:

FILENAME_MAX

which expands to an integer constant expression that is the
size needed for an array of char large enough to hold the
longest file name string that the implementation guarantees
can be opened;

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
K

Keith Thompson

Richard G. Riley said:
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space. [snip]
Why is it possible to assign strings to szFile bigger than space is
allocated?

One of the things to keep in mind that HW Segmentation doesnt run to
that level. You basically have a big block of memory. C assumes you
take care of certain things like buffer over runs : it is one of the
reasons it is so efficient : you need to keep tabs of this yourself.

HW segmentation doesn't *necessarily* run to that level. Given
sufficient hardware and compiler support, an implementation could
allocate each individual object (malloc()ed block or declared object)
in its own memory segment, and trap any attempts to access memory
beyond the bounds of the intended object.

Few, if any, real-world implementations do this, but you shouldn't
make assumptions either way. A segmentation fault almost certainly
implies that you've invoked undefined behavior (though not necessarily
at the point where the fault occurs), but the reverse implication
doesn't hold.

The point is that "undefined behavior" is probably even more undefined
than you think it is, even if you take this rule into account.
 
J

Jack Klein

Hi,
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space.


function with recursion...
char *szFile = NULL,
...
while((ptrDirentry = readdir(ptrDir)) != NULL) {

[snip]

Never mind that, there is a far more important question here. Namely,
why are you writing outdated, discredited, Microsoft Hungarian
notation crap on Linux?

Note that even Microsoft has given up on it.
 
T

Thomas Barth

Am 02/21/2006 05:29 AM schrieb Jack Klein:
function with recursion...
char *szFile = NULL,
...
while((ptrDirentry = readdir(ptrDir)) != NULL) {

[snip]

Never mind that, there is a far more important question here. Namely,
why are you writing outdated, discredited, Microsoft Hungarian
notation crap on Linux?

I like that style. I ve seen part of the sourcecodes of Windows 2000 two
years ago. I was quite impressed. I dont care of what os I am
programming for.
>
Note that even Microsoft has given up on it.

How do you know that? Have you seen the sourcecodes of WindowsXP/Vista?

Btw. thanks for all your good pieces of advises!

T h o m a s B
 
R

Richard G. Riley

Richard G. Riley said:
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space. [snip]
Why is it possible to assign strings to szFile bigger than space is
allocated?

One of the things to keep in mind that HW Segmentation doesnt run to
that level. You basically have a big block of memory. C assumes you
take care of certain things like buffer over runs : it is one of the
reasons it is so efficient : you need to keep tabs of this yourself.

HW segmentation doesn't *necessarily* run to that level. Given
sufficient hardware and compiler support, an implementation could
allocate each individual object (malloc()ed block or declared object)
in its own memory segment, and trap any attempts to access memory
beyond the bounds of the intended object.

There are many "coulds" there and nothing helpful to a newbie trying t
understand why he should be careful not to overwrite unprotected memory.
Few, if any, real-world implementations do this, but you shouldn't
make assumptions either way. A segmentation fault almost certainly
implies that you've invoked undefined behavior (though not necessarily
at the point where the fault occurs), but the reverse implication
doesn't hold.

Of course and no one said any different.
The point is that "undefined behavior" is probably even more undefined
than you think it is, even if you take this rule into account.


Possibly more undefined than you think I think :-; But again, I dont
see how this has anything to do with advising a new programmer on
being careful with pointers and memory allocations : a cornerstone of
C programming.

As you will recall the OP "expected" a seg fault : I pointed out that
that is not necessarily the case - so we seem to have come full about
for some reason.
 
K

Keith Thompson

Richard G. Riley said:
Richard G. Riley said:
I would like to create a file index like updatedb on Linux does as a
part of my program, but I dont know how long the filenames could be.
Therefore I want to use malloc to keep the size of the filenames
flexible. I would expect an segmentation fault with the following
sourcecode, when invoking strcat or sprintf to assign the first value to
szFile because of missing space. [snip]
Why is it possible to assign strings to szFile bigger than space is
allocated?

One of the things to keep in mind that HW Segmentation doesnt run to
that level. You basically have a big block of memory. C assumes you
take care of certain things like buffer over runs : it is one of the
reasons it is so efficient : you need to keep tabs of this yourself.

HW segmentation doesn't *necessarily* run to that level. Given
sufficient hardware and compiler support, an implementation could
allocate each individual object (malloc()ed block or declared object)
in its own memory segment, and trap any attempts to access memory
beyond the bounds of the intended object.

There are many "coulds" there and nothing helpful to a newbie trying t
understand why he should be careful not to overwrite unprotected memory.

It could help a newbie understand why he gets a seg fault when he runs
his program on one system, and doesn't get a seg fault when he runs it
on another system.

What you wrote could imply that a buffer overrun *won't* cause a seg
fault. My point is that it may or may not.

In any case, I wasn't necessarily talking just to the OP. This is a
public forum, after all. And even if my point went over the OP's head
(an assumption I do not make), it can't hurt to be aware that there
are details beyond what he's already learned.

[snip]
Possibly more undefined than you think I think :-;

It was meant as a general "you", not you personally.
But again, I dont
see how this has anything to do with advising a new programmer on
being careful with pointers and memory allocations : a cornerstone of
C programming.

As you will recall the OP "expected" a seg fault : I pointed out that
that is not necessarily the case - so we seem to have come full about
for some reason.

Your point was that one shouldn't assume anything about what happens
on a buffer overflow. I was just emphasizing that point; sometimes
you get a seg fault, sometimes you don't.
 
R

Richard G. Riley

Your point was that one shouldn't assume anything about what happens
on a buffer overflow. I was just emphasizing that point; sometimes
you get a seg fault, sometimes you don't.

We are in agreement then :-; And thanks for the clarification to my
other post about the unsigned char - better to be 100% clear althought
I would be surprised if there were any differences in the
outcome. Hmm. Or would there?
 
M

Michael Wojcik

FILENAME_MAX

which expands to an integer constant expression that is the
size needed for an array of char large enough to hold the
longest file name string that the implementation guarantees
can be opened;

Unfortunately, FILENAME_MAX is not reliable, in that there are
implementations which claim conformance but provide infelicitous
values for FILENAME_MAX, and argue that these are within the letter
of the standard. See for example [1], part of a discussion about
HP-UX 11's use of 14 for FILENAME_MAX.

While not everyone will agree with the arguments made in that thread
(and note that it's Alan Balmer - who I hope we can agree knows
something about C - who's defending HP here), the practical result is
that FILENAME_MAX cannot portably be used in the manner that a
cursory reading of the standard might suggest.

I'll note that the final clause you quoted above appears to give an
implementation plenty of weasel room; an implementation need not
"guarantee" that any file of any name "can be opened".

My view, frankly, is that FILENAME_MAX is inherently broken anyway,
since there are plenty of implementations that can produce programs
for execution environments which they cannot have full knowledge of.
Compiler authors are not oracles. We're stuck with FILENAME_MAX for
compatibility, but I believe new code should avoid it.


1. http://groups.google.com/group/comp.lang.c/msg/7224d5e9ae3f8a3f
 

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
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top