Re: A malloc question, part 2



"Why Tea" <ytlim1@xxxxxxxxx> writes:
Thanks to those who have answered my original question. I thought I
understood the answer and set out to write some code to prove my
understanding. The code was written without any error checking.

There are also some dangerous things in your code. I'll point them
out (without necessarily answering your actual question).

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

typedef struct {
char s[23];
int n;
} SomeStruct;

typedef struct {
char user[32];
int age;
char others[100];
} UserStruct;

void my_test_func(int cnt)
{
SomeStruct *p, *q;
UserStruct *x, *y;

printf("Size of SomeStruct=0x%X\n", sizeof(SomeStruct));

The "%X" format expects an unsigned int. You're giving it a size_t,
which is not necessarily the same type. Try this:

printf("Size of SomeStruct=0x%lX\n",
(unsigned long)sizeof(SomeStruct));

p = malloc(cnt*sizeof(SomeStruct));
q = p + 1;
printf("p=0x%X, q=0x%X. q-p=0x%X\n", p, q, (int)q-(int)p);

Here you're using "%X" to print pointer values; that's also a no-no.
Use "%p" and convert each pointer to void*:

printf("p=%p, q=%p\n", (void*)p, (void*)q);

You're also converting pointer values to type int, which is legal, but
the results are implementation-defined (and I've worked on systems
with odd pointer formats where the results of such conversions are not
particularly meaningful).

But pointer subtraction is defined by the language; it yields a result
of type ptrdiff_t (which is a typedef for some signed integer type).
The result of q-p is going to be 1, because the result is scaled by
the size of the pointed-to type. If you want the difference in bytes,
convert each pointer to char*:

printf("p=%p, q=%p, q-p=%ld\n",
(void*)p, (void*)q, (char*)q-(char*)p);

Note that we convert to char*, not to void*, since pointer arithmetic
is not defined for void* (the pointed-to type has no size) -- though
some compilers may support it as an extension.

x = (UserStruct *)(p);
y = x + 1;
printf("x=0x%X, y=0x%X. y-x=0x%X\n", x, y, (int)y-(int)x);

As above.

free(p);
}

int main(int argc, char argv[])

The correct declaration for argv is "char *argv[]" or "char **argv".
But since you're not actually using either argc or argv, you might as
well declare it as:

int main(void)

{
printf("Size of UserStruct=0x%X\n", sizeof(UserStruct));

"%X" expects an unsigned int, but you're giving it a size_t; see above.

my_test_func(sizeof(UserStruct));

my_test_func() takes an argument of type int, but you're passing it a
size_t. This isn't likely to be a problem in this case; since
my_test_func() isn't variadic, and its declaration is visible, the
compiler will automatically generate an implicit conversion from
size_t to int, which is likely to preserve the correct value in this
case. Nevertheless, it would be better to declare my_test_func() with
a parameter of type size_t.

return 1;

Why are you returning the value 1 from main()? On some systems, this
indicates an error condition; on others, it may be meaningless. The
only portable values you can return from main() are 0, EXIT_SUCCESS,
and EXIT_FAILURE.

}
[snip]

It's likely that none of these errors will cause any actual problems
*on many systems*. But your code could break badly if you try to
compile and execute it on a system with different characteristics
(e.g., where int and pointers have different sizes, or are passed as
arguments in different ways).

--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <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.
.



Relevant Pages

  • Re: Insufficient guarantees for null pointers?
    ... will the compiler know what the bounds are after converting that char * ... to an int *, if it could point to either of two arrays which happen to ... compares equal to the original pointer. ...
    (comp.std.c)
  • Re: problem with memcpy and pointers/arrays confusion - again
    ... int line, unsigned long *total_mem) ... That's a long pointer address... ... If sizeof > sizeof which is ... if you allocate for char with sizeof < sizeof, ...
    (comp.lang.c)
  • Re: Request critique of first program
    ... Returns a pointer to an asplit_result struct (unless unable to ... Success is indicated by SUCCESS, ... const char *out_file_b, ... const long int num_lines); ...
    (comp.lang.c)
  • Re: static in [ ]
    ... void someFunc (int size, char a) ... and passing a pointer to fewer than size characters is fine. ...
    (comp.lang.c)
  • Re: I dont understand typedef example
    ... * Using typedef, declare 'func' to have type ... 'function taking two int arguments, ... declared ptr as a pointer object that can points to a function of the ...
    (comp.lang.c)