4
  1. What is the difference between

    int size;
    int *arr;
    scanf("%i", &size);
    arr = malloc(size * sizeof(*arr));
    

    and

    int size;
    scanf("%i", &size);
    int arr[size];
    
  2. When I want to allocate memory for 2 big numbers i would use the following code:

        unsigned long *big_nums;
        big_nums = malloc(2 * sizeof(*big_nums));
    

    I would access the first big bumber using big_nums[0] an the seond one with big_nums[1]. Let's say unsigned long is 4 bytes big, then the code would allocate 2 * 4 = 8 bytes. Let's say I do something like this:

        unsigned long *big_nums;
        big_nums = malloc(7);
    

Using big_nums[0] is clear for me, but how about big_nums[1]? Will it cause some kind of segmentation fault error or what?

1
  • 1
    big_nums = malloc(2 * sizeof(big_nums)); should be ... = malloc(2 * sizeof big_nums[0]) Commented Nov 22, 2013 at 17:39

3 Answers 3

2

There are two places to get memory from: the stack and the heap. The stack is where you allocate short lived things, and the heap is for allocating long term things.

malloc() allocates from the heap, and int arr[size] allocates from the stack.

When your function exits, arr[size] will be disposed of automatically, but malloc() will not. This leads to what's called "memory leaks".

big_nums = malloc(7);

will indeed be an error if you access big_nums[1]. In general the standard says behavior is "undefined" which means it could work, or might not.

Sign up to request clarification or add additional context in comments.

1 Comment

Your first paragraph isn't really true. Stack vs. heap has nothing to do with short vs. long-lived objects, and has everything to do with whether the object needs to survive past the end of the function, or if it's too big to be allocated on the stack, or if the size can't be known until runtime.
1

For Q#1: The second version will (try to) allocate a variable-length array on the stack. In C99 onwards, this is possible; but in traditional C variable-length arrays don't exist, and you must roll them yourself using malloc.

6 Comments

As far as I see the C99 was introducted in 1999, so quite a long time ago. Does it mean I can go ahead with using it's features with no fear of compatibility?
Hopefully yes. In a good world we would all use C99, but there are two caveats. (1) Microsoft compilers don't support it. (2) Some projects, such as the Linux kernel stick to a pre-99ish style, and might not approve of VLAs. If neither of these concern you, the only question is whether you really want to allocate on the stack. For small arrays, go ahead!
(1) is not accurate, Visual Studio 2013 supports partially C99.
@Étienne Actually that blog post only talks about the standard library. There is no sign that language features (such as variable-length arrays) are included.
|
0

For Q#2: You will be allowed to make that error. And when you write to the second element of the array, you will overwrite one byte that does not "belong" to you.

My guess is that in most cases, nothing bad will happen because malloc(7) will secretly be equivalent to malloc(8). But there is NO GUARANTEE of this. Anything could happen, including a segfault or something worse.

By the way, if you have two separate questions, it would be best to write them up as two separate questions. You get more points way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.