4

Here is the example:

#include <stdio.h>

struct nums {
    int x;
    int y;
};

int main() {
    struct nums *ball = malloc(sizeof *ball * 4);
    ball[0].x = 2;
    printf("%d", ball[0].x);
    free(ball);
};

Error Details:

Exception thrown: write access violation.
**ball** was 0x6E919550.

I am very new to C and I would really appreciate someone to explain what specifically I am telling the computer to do here, why it is incorrect and also show me the correct way of doing this. Thanks.

EDIT: This seems to be functional code but does not run when I compile and run it in VS16 why could this be?

ripytide
  • 327
  • 2
  • 14
  • 1
    You should do `sizeof(struct nums)` instead of `*ball`. This is a legit question why people downvote? – Tony Tannous Feb 14 '21 at 14:07
  • what is the exact error you are getting, please paste it here. – roottraveller Feb 14 '21 at 14:07
  • Please review the question guidelines and consider changing your question to focus on a single and definitively answerable issue. – possum Feb 14 '21 at 14:08
  • The change of ```*ball``` to ```struct nums``` does not change the error received .;( – ripytide Feb 14 '21 at 14:12
  • @possum The issue is it causes an memory violation exception? – ripytide Feb 14 '21 at 14:13
  • 4
    There is nothing wrong with `sizeof *ball`. In fact, many people prefer it over `sizeof(struct nums)`. It does not matter that `ball` is uninitialized since `sizeof` is a compile-time operation. – 001 Feb 14 '21 at 14:21
  • 2
    `You should do sizeof(struct nums) instead of *ball` No, I would advise to prefer `*ball` instead of `sizeof(struct nums)`, so that when you later refactor the code and change `ball` type, you don't have to track and change each `malloc` statement. – KamilCuk Feb 14 '21 at 14:22
  • 1
    @Ripytide Did you `#include `? See ex. https://stackoverflow.com/questions/44504429/c-write-access-violation https://stackoverflow.com/questions/55454761/write-acces-violation-after-using-malloc-inside-a-function – KamilCuk Feb 14 '21 at 14:23
  • @KamilCuk it's more comprehensive and clear to use `struct nums` than searching for the definition of `*ball` but that is opinion based I guess. – Tony Tannous Feb 14 '21 at 14:25
  • 1
    There's `#include ` in your code. For `malloc` you need also `#include `. Add `#include ` on top of your source file (above or below `stdio` one) and recompile and run your program again - does the problem solve itself then? – KamilCuk Feb 14 '21 at 14:26
  • Thanks @KamilCuk that fixes it, I will now go learn about ```stdlib.h``` ;) – ripytide Feb 14 '21 at 14:28
  • 2
    @TonyTannous The point of using `sizeof *ball` is that you do *not* need to go searching for the declaration. `sizeof *ball` is guaranteed to be correct, but `sizeof(struct foo)` is wrong if ball is not a pointer to struct foo. `sizeof *ball` is the better idiom. – William Pursell Feb 14 '21 at 14:30
  • 2
    First thing you should do is to always compile with `-Wall -Wextra` and pay attention to the warnings. – klutt Feb 14 '21 at 14:40
  • @TonyTannous `sizeof *ball` is better. It is easier to code right the first time, easier to review and maintain than `sizeof(struct nums)`. The "more comprehensive" argument is simple more to get wrong. – chux - Reinstate Monica Feb 14 '21 at 14:43
  • 1
    @Ripytide Whoever or whatever text suggested `struct nums *ball = malloc(sizeof *ball * 4);` is more up to date than others. – chux - Reinstate Monica Feb 14 '21 at 14:45
  • @chux-ReinstateMonica Yes, I realized after that it was because OP hadn't included stdlib, stupid of me to ignore such an obvious thing. I'll delete my comment to avoid further confusion. – mediocrevegetable1 Feb 14 '21 at 14:51
  • @chux-ReinstateMonica I crafted this short example myself and used ```* ball``` due to me learning about it here on SO when troubleshooting. I will go ahead and pat myself on the back :) – ripytide Feb 14 '21 at 22:42

1 Answers1

3

The most likely problem is a missing declaration for malloc(). You should add the line

#include <stdlib.h>

at the top of your code.

Without this line, the compiler may assume that malloc returns int. But if you're on a 64-bit platform, with 32-bit ints but 64-bit pointers, this will fail pretty badly. Your pointer variable ball is likely to end up holding just 32 of the 64 bits which malloc tried to return, with the other 32 scraped off. ball will therefore be an invalid pointer, leading to the exception you saw.

Did you get any warnings? My compiler complains

warning: implicitly declaring library function 'malloc'
note: include the header <stdlib.h>

Or, you might have gotten a message like

warning: implicit declaration of function 'malloc' is invalid in C99

If you got warnings like these, please don't ignore them, and do learn what they mean: they're definitely things you care about. And if you didn't get warnings like these, you should figure out how to enable them in your compiler. (Or if that's not possible, you should strongly consider switching to a better compiler, if at all possible.) Modern C programming practice definitely considers this error to be one worth warning about. And there are lots of mistakes like this that are easy to make, that are frustrating to debug, and that a good compiler will warn you about, at least if you let it.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103