Dmitri,
The clang code generator and static analyzer are very smart — I’m pretty sure
that, for a small malloc where a pointer to the data is never passed outside
the current function, the malloc/free can be replaced with a buffer in on the
stack — equivalent of alloca().
WAYRTTD? Your test case may be too contrived.
Are you just trying to understand why malloc() is getting optimized out or are
you trying to find an actual bug?
If you’re testing for a compiler bug, pass the pointer to an external function
whose implementation the complier can’t see:
create a file foo.c containing
void foo(char* baz);
void foo(char* baz)
{
// whatever logging you want
}
then in your code:
void foo(char* baz);
if(data == NULL) {
printf("data == NULL\n");
return 1;
} else {
foo(data);
for(size_t i = 0; i < need_size; ++i) {
#if 0
size_t c = i % 64;
c += 63;
data[i] = c;
#else
data[i] = 'A';
#endif
}
printf("data != NULL <<%c>>\n", data[0x10000]);
}
free(data);
For instance, in your code, if the compiler can see you’re only touching the
first 100 bytes of *data and you’re never doing anything that could pass a
pointer to the data out of scope, it could just return a pointer to a 100 byte
block on the stack and no-op the malloc and free and still generate correct
behavior. You can defeat this by making the code between malloc() and free()
sufficiently complex.
Also, you may want to check out this document:
https://developer.apple.com/library/prerelease/content/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html
as it has a fair bit of information about how malloc actually works.
HTH,
-Steve
> On Jul 4, 2016, at 4:48 PM, Dmitry Markman <[email protected]> wrote:
>
> another observation
>
> the following code
>
>
> char *data = (char *)malloc(need_size);
>
> if(data == NULL) {
> printf("data == NULL\n");
> return 1;
> } else {
> for(size_t i = 0; i < need_size; ++i) {
> #if 0
> size_t c = i % 64;
> c += 63;
> data[i] = c;
> #else
> data[i] = 'A';
> #endif
> }
> printf("data != NULL <<%c>>\n", data[0x10000]);
> }
> free(data);
>
>
> returns
>
> data != NULL <<A>>
> Program ended with exit code: 0
>
> but if you replace #if 0 to #if 1
>
> it started to behave correctly (data = NULL)
>
> dm
>
>
>
>
>
>
>> On Jul 4, 2016, at 4:20 PM, Carl Hoefs <[email protected]>
>> wrote:
>>
>>
>>> On Jul 4, 2016, at 12:58 PM, Clark Cox <[email protected]> wrote:
>>>
>>> Malloc effectively *never* returns NULL.
>>
>> It does seem that malloc returns NULL on error...
>>
>> #include <stdlib.h>
>> #include <stdio.h>
>>
>> int main(int argc, const char * argv[]) {
>> size_t need_size = 0x1000000000000;
>>
>> char *data = "dummy"; // data ptr is not NULL
>> data = malloc(need_size); // data ptr overwritten
>>
>> if(data == NULL) {
>> printf("ERROR data == %p\n",data); // <----- data is NULL
>> return 1;
>> } else {
>> printf("OKAY data != NULL: %p\n",data);
>> }
>> data[0] = 'c';
>>
>> free(data);
>>
>> return 0;
>> }
>>
>> mtest(3008,0x7fff786d1300) malloc: *** mach_vm_map(size=281474976710656)
>> failed (error code=3)
>> *** error: can't allocate region
>> *** set a breakpoint in malloc_error_break to debug
>> ERROR data == 0x0
>>
>>
>
> Dmitry Markman
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Xcode-users mailing list ([email protected]
> <mailto:[email protected]>)
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/xcode-users/sgs-lists%40codewell.com
> <https://lists.apple.com/mailman/options/xcode-users/sgs-lists%40codewell.com>
>
> This email sent to [email protected] <mailto:[email protected]>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/xcode-users/archive%40mail-archive.com
This email sent to [email protected]