1

In a program I'm writing, I have an array of accounts(account is a struct I made). I need this visible to all functions and threads in my program. However, I won't know the size it has to be until the main function figures that out. so I created it with: account *accounts;

and try to allocate space to it in main with this:

number of accounts = 100 //for example
accounts = (account*)malloc(numberOfAccounts * sizeof (account));

However, it appears to be sizing the array larger than it needs to be. For example, accounts[150] exists, and so on.

Is there anything I am doing wrong? How can I get the size of accounts to be exactly 100? Thanks

10
  • 4
    How are you determining that the array is "larger than it needs to be"? Commented Mar 8, 2011 at 20:10
  • Ok, what do u mean by " For example, accounts[150] exits ", did u validate the data that you found at accounts[150] ? Commented Mar 8, 2011 at 20:11
  • Don't forget to always check the return value of malloc (and realloc): account = malloc(); if (account == NULL) /* no memory */; Commented Mar 8, 2011 at 20:13
  • I meant exists. For example, I can place an account into accounts[150] Commented Mar 8, 2011 at 20:14
  • u cannot guarantee, whether the space u requested is actually returned by malloc(). This program seems to be correct unless u get Out Of Memory exception. Commented Mar 8, 2011 at 20:15

6 Answers 6

5

You can't do that - malloc() doesn't provide any guarantees about how much memory it actually allocates (except that if it succeeds it will return a pointer to at least as much as you requested). If you access anything outside the range you asked for, it causes undefined behaviour. That means it might appear to work, but there's nothing you can do about that.

BTW, in C you don't need to typecast the returned value from malloc().

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

Comments

4

Even though it may look like it, accounts[150] does not truly exist.

So why does your program continue to run? Well, that's because even though accounts[150] isn't a real element, it lies within the memory space your program is allowed to access.

C contains no runtime checking of indexes - it just calculates the appropriate address and accesses that. If your program doesn't have access to that memory address, it'll crash with a segmentation fault (or, in Windows terms, an access violation). If, on the other hand, the program is allowed to access that memory address, then it'll simply treat whatever is at that address as an account.

If you try to modify that, almost anything can happen - depending on a wide variety of factors, it could modify some other variables in your program, or given some very unlucky circumstances, it could even modify the program code itself, which could lead to all kinds of funky behavior (including a crash). It is even possible that no side effects can ever be observed if malloc (for whatever reason) allocated more memory than you explicitly requested (which is possible).

If you want to make sure that such errors are caught at runtime, you'll have to implement your own checking and error handling.

Comments

1

I can't seem to find anything wrong with what you provide. If you have a struct, e.g.:

struct account{
  int a,b,c,d;
  float e,f,g,h;
}

Then you can indeed create an array of accounts using: struct account *accounts = (struct account *) malloc(numAccounts * sizeof(account)); Note that for C the casting of void* (retun type of malloc) is not necessary. It will get upcasted automatically.

[edit] Ahhh! I see your problem now! Right. Yes you can still access accounts[150], but basically what happens is that accounts will point to some memory location. accounts[150] simply points 150 times the size of the struct further. You can get the same result by doing this: *(accounts + 150), which basically says: Give me the value at location accounts+150.

This memory is simply not reserved, and therefore causes undefined behavior. It basically comes down to: Don't do this!

2 Comments

you should use the markdown facilities for formatting instead of doing the HTML yourself.
@Carl you are right, I couldn't find them anywhere, but it's ok now, thanks!
0

Your code is fine. When you say accounts[150] exits do you mean exits or exists?

If your code is crashing when accessing accounts[150] (assuming numberOfAccounts = 100) then this is to be expected you are accessing memory outside that you allocated.

If you meant exists it doesn't really, you are just walking off the end of the array and the pointer you get back is to a different area of memory than you allocated.

1 Comment

I meant exists. For example, I can place an account into accounts[150]
0

Size of accounts is exacly for 100 structures from malloc result pointer starts if this address is non-zero.

Comments

0

Just because it works doesn't mean it exists as part of the memory you allocated, most likely it belongs to someone else.

C doesn't care or know that your account* came from malloc, all it knows is that is a memory pointer to something that is sizeof(account).

accounts[150] accesses the 150th account-sized object from the value in the pointer, which may be random data, may be something else, depending on your system it may even be your program.

The reason things seem to "work" is that whatever is there happens to be unimportant, but that might not always be the case.

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.