简体   繁体   English

使用Malloc在C中分配数组大小

[英]Using Malloc to allocate array size in C

In a program I'm writing, I have an array of accounts(account is a struct I made). 在我编写的程序中,我有一个帐户数组(account是我制作的一个结构)。 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; 所以我用以下方式创建它:account * accounts;

and try to allocate space to it in main with this: 并尝试使用main为其分配空间:

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. 例如,存在accounts[150] ,依此类推。

Is there anything I am doing wrong? 我做错了什么吗? How can I get the size of accounts to be exactly 100 ? 我怎样才能使帐户的大小恰好是100 Thanks 谢谢

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). 您无法做到这一点malloc()不能保证其实际分配了多少内存(除非成功执行,否则它将至少返回您所请求的指针)。 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() . 顺便说一句,在C语言中,您无需强制转换malloc()返回的值。

Even though it may look like it, accounts[150] does not truly exist. 尽管看起来很像,但accounts[150]并不真正存在。

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. 好吧,这是因为即使accounts[150]不是一个真正的元素,它也位于程序可以访问的内存空间内。

C contains no runtime checking of indexes - it just calculates the appropriate address and accesses that. C不包含索引的运行时检查-它仅计算适当的地址并对其进行访问。 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). 如果您的程序无权访问该内存地址,则会因分段错误(或以Windows术语为访问冲突)而崩溃。 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 . 如果,另一方面,该程序允许访问的内存地址,然后它会简单地把什么是在该地址作为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). 如果malloc(无论出于何种原因)分配的内存比您显式请求的内存更多(可能的话),甚至有可能看不到任何副作用。

If you want to make sure that such errors are caught at runtime, you'll have to implement your own checking and error handling. 如果要确保在运行时捕获到此类错误,则必须实施自己的检查和错误处理。

I can't seem to find anything wrong with what you provide. 您提供的内容似乎找不到任何问题。 If you have a struct, eg: 如果您有结构,例如:

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)); 然后,您确实可以使用以下方式创建一组帐户: struct account *accounts = (struct account *) malloc(numAccounts * sizeof(account)); Note that for C the casting of void* (retun type of malloc) is not necessary. 请注意,C的铸造void* (retun类型的malloc)是没有必要的。 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. 是的,您仍然可以访问帐户[150],但是基本上发生的情况是accounts将指向某个内存位置。 accounts[150] simply points 150 times the size of the struct further. accounts[150]仅仅指出结构的150倍。 You can get the same result by doing this: *(accounts + 150) , which basically says: Give me the value at location accounts+150. 通过执行以下操作,您可以获得相同的结果: *(accounts + 150) ,它基本上说:给我在location accounts + 150处的值。

This memory is simply not reserved, and therefore causes undefined behavior. 该内存根本没有保留,因此会导致未定义的行为。 It basically comes down to: Don't do this! 基本上可以归结为:不要这样做!

Your code is fine. 您的代码很好。 When you say accounts[150] exits do you mean exits or exists? 当您说帐户[150]退出时,是指退出还是存在?

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. 如果访问帐户[150]时代码崩溃(假设numberOfAccounts = 100),则可以预期您正在访问分配的内存之外的内容。

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. 如果您认为存在并不是真的,那么您只是走出了数组的末端,而返回的指针指向的内存与分配的内存不同。

如果该地址不为零,则从malloc结果指针开始算起,该帐户的大小恰好为100结构。

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). C不在乎或不知道您的帐户*来自malloc,它所知道的仅是指向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. account [150]从指针中的值访问第150个帐户大小的对象,该值可能是随机数据,也可能是其他内容,这取决于您的系统甚至可能是您的程序。

The reason things seem to "work" is that whatever is there happens to be unimportant, but that might not always be the case. 事情似乎“起作用”的原因是,发生的任何事情都不重要,但事实并非总是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM