4

I'm working on a display interface with C. Here is the simplified code:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define A_BITMAP {1,2,3}
    void getA(int **a){
        a[0]=(int*)malloc(12);
        memcpy(a[0],(int[])A_BITMAP,12);                                                                                                            
    }
    void main(){
        int* a;
        getA(&a);
        printf("%d",a[2]);
        free(a);
    }

A_BITMAP is one picture's bitmap array, and I cannot modify its code. Here is my question:

  1. Is there any way not using memcpy() to assign to the malloc(ed) area with macro A_BITMAP?

  2. Will (int[])A_BITMAP generate a large local array on stack? The picture's size is about 2M, is it safe to do so?

qweeah
  • 199
  • 2
  • 10
  • 5
    Side-note: [Dont cast malloc](http://stackoverflow.com/a/605858/143279) – implmentor Aug 20 '15 at 07:03
  • 2
    Your sizes are all wrong. You malloc 3 bytes; you attempt to copy 2 bytes into it, from an array of `int` (which are probably 4 bytes each). Answers: (1) No — unless you wrap the array in a structure; (2) No — not with the 3 integer array shown. If you mess with a big array, then the data for the 'compound literal' will be stored somewhere, but not necessarily on the stack. – Jonathan Leffler Aug 20 '15 at 07:06
  • Why don't you create a global variable? It won't be on the stack. – Karoly Horvath Aug 20 '15 at 07:21
  • @JonathanLeffler Could u plz tell me where is the 'compound literal'? .data? These code will be in userspace. thx – qweeah Aug 20 '15 at 07:29
  • 1
    The compound literal could be anywhere; the compiler chooses. In this case, it could even be in the text segment since the `memcpy()` function promises not to modify it. But the compiler might have a copy in the text segment that gets copied to space in the stack or the data segment, before being passed to the function — because the compound literal is, in general, modifiable. It all depends on the compiler. – Jonathan Leffler Aug 20 '15 at 07:31

2 Answers2

1

You can cast it like that. However, casting should be avoided as it's basically telling the compiler you know better than it and disabling any sanity checks it can do. Also, as apparently you don't really know that A_BITMAP is going to be 3 ints, you're opening yourself up to a whole load of pain by hard coding the size.

Moreover, as pointed out by Sunny, it'll likely copy the array onto the stack when written like that (this depends on your compiler, but it's not something I'd like to risk). You really don't want a 2Mb array on the stack, trust me.

A couple of other points:

  • a isn't an array, it's a pointer so use *a, not a[0], as it's confusing to the reader
  • you don't return a result from main which means your program exits with an error.

You might want to consider something like this:

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

#define A_BITMAP {1,2,3}

void getA(int **a) {
    static int data[] = A_BITMAP;
    *a = malloc(sizeof(data));
    memcpy(*a, data, sizeof(data));
}
int main(){
    int* a;
    getA(&a);
    printf("%d\n", a[2]);
    free(a);
    return 0;
}
Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
0

It will create the array on the stack each time the function is called. It will be better if you declare A_BITMAP as a global array as it will not be allocated on stack.

Sunny
  • 517
  • 5
  • 17