C(++)malloc混淆

时间:2010-02-23 14:57:13

标签: c++ arrays malloc

我只是没有进一步为C中的数组分配内存,主要是C ++。 我已经找了一些例子,但对我来说没有任何有用的例子,至少看起来如此。

所以如果我在这里有一个typedef:

typedef struct
{
int x;
int y;
} Coordinate;

Coordinate* myList;

我也有Coordinate类型的数组,如何动态地附加项目。 我所知道的是,我必须在C中使用malloc和更晚free,在C ++中使用new / delete。 (Malloc吓坏了我)

所以我的目标是这样的功能:

void AddSomething ( int x, int y )
{
// myList malloc/new magic here
}

我的问题是:

  • 如何为myList分配新内存然后将新项添加到其中的行必须如何? 你能否告诉我一个C和C ++的工作示例?

  • C中的malloc究竟是如何工作的?有一些我不熟悉的事情(在函数之前有一些指针,并且分配的变量设置为malloc的返回值)

7 个答案:

答案 0 :(得分:14)

使用vector来完成这项工作。

#include <vector>

typedef struct
{
int x;
int y;
} Coordinate;

std::vector<Coordinate> coordinates;

Coordinate newCoord;
newCoord.x = 1;
newCoord.y = 1;

coordinates.push_back(newCoord);

其他信息: 要了解malloc / free和new / delete,您可以阅读

章节

13:动态对象创建

在布鲁斯埃克尔斯Thinking C++ Volume 1。它是一本可以免费下载的书。

答案 1 :(得分:5)

对于C,以下内容将创建一个包含单个坐标的列表:

myList = malloc(sizeof(Coordinate));

如果要分配大小为n的数组,请执行以下操作:

myList = malloc(n * sizeof(Coordinate));

在C ++中,大小为n的数组的代码如下所示:

myList = new Coordinate[n];

对于C ++情况,您的类必须具有默认构造函数,Coordinate类具有隐式构造函数。但是对于C ++,我强烈建议使用std::vector<Coordinate>而不是手动管理的数组。

顺便说一句,您也可以使用malloc()在C ++中分配内存,但它只分配原始内存,而使用new也会触发对构造函数的调用。在你的结构的情况下,没有区别,因为它是一个POD结构,不需要构造函数。另外,请记住,如果使用malloc()在C ++中分配内存,则必须使用free()来释放内存;如果您正在使用new,则需要使用delete - 将两者混合可能会产生非常有趣的结果,这些结果无法调试。使用new,您还必须确保匹配正确的调用类型。使用new创建的任何内容都需要使用delete进行清理,并且需要使用delete[]删除使用数组新创建的内容,如上例所示。

答案 2 :(得分:3)

对于这样的问题,第一个回复必须是另一个问题。具体来说,是否有一些真的有充分理由不能使用std::vector?除非你真的,真的,绝对不能,这是正确的做法。

否则,你唯一真正的选择是写{又一个}模仿std::vector。虽然我不认识你,但经验表明你写的东西可能不会那么好。

答案 3 :(得分:1)

  

Malloc吓坏了我

警惕手动管理的动态记忆是一个好主意 - 有很多机会犯错误;很难调试错误---但不需要害怕。

malloc做的是询问操作系统是否存在至少这么大的内存。就这样。 你必须使用指针来跟踪它,因为编译器不知道操作系统会为你选择什么内存,因此无法在编译时将变量名称连接到该位置。 < / p>

free所做的是告诉操作系统,我已完成此内存并且不会再次使用。这就是全部

C ++的newdelete也以相应的构造函数或析构函数的形式调用初始化和终结例程。我不会对此说“全部”,因为 业务中有一些细节。

因此,要成功使用动态分配,您应该

  • 在尝试使用之前询问你需要的内存,并检查你确实有一些(操作系统可以说“不,你不能拥有它。”你知道)< / LI>
  • 确保您初始化它(在c ++中编写正确的构造函数或在c中自己管理它)
  • 不要忘记它。
  • 确保在回馈之前管理任何所需的清理(c ++中的析构函数,c中的手动)。这可能是整个企业中最难的部分。
  • 之后再也不要使用内存

答案 4 :(得分:0)

C malloc只是分配内存,但不“构造”一个​​对象。在C ++中,通常使用new,它会分配和构造对象。主要区别是new在分配RAM后调用构造函数。 malloc只是一个“愚蠢”的内存管理器,但对于某些需要非类型原始内存的特定情况,它可能会表现得更好。

newmalloc都“返回”指针。指针是一个地址。所以这是两者的形式,它们是赋值表达式。

Coordinate * notObject = (Coordinate*)malloc(sizeof(Coordinate));
Coordinate * object = new Coordinate();

注意,malloc会返回void *,因此您必须投弃它。键入new,因此不需要强制转换。

答案 5 :(得分:0)

  
      
  • 如何为myList分配新内存然后将新项目添加到其中的行必须如何?你能告诉我一个C和C ++的工作示例吗?
  •   

实际上有两种不同的选择:您可以使用以下方法创建Coordinate个对象数组:

Coordinate *list = new Coordinate[ 42 ]; // list can hold at most 42 objects

或者,使用链接列表,当然要求您更改Coordinate数据类型的定义:

typedef Coordinate_t {
    int x, y;
    Coordinate_t *next;
};

在链表中插入有点复杂。

当然,如果您使用的是C,则无法使用new运算符,而是必须使用malloc

Coordinate *list = malloc(*list * 42); /* list can hold at most 42 objects */
  
      
  • C中的malloc究竟是如何工作的?有一些我不熟悉的事情(在函数之前有一些指针,并且分配的变量设置为mallocs返回值)
  •   

分配函数使用某些特定于操作系统的API从免费存储区请求一些内存(因此这取决于实现)。例如:在* nix上,使用名为sbrk的系统API和朋友。

答案 6 :(得分:0)

#include <stdlib.h>

struct
{
int x;
int y;
} Coordinate;

Coordinate* myList = 0;

int myListLength = 0;  // initialize myListLength to size of myList

void AddSomething ( int x, int y )
{
    int i;
    // malloc returns a void pointer, so we cast it to be a Coordinate *
    Coordinate* newList = (Coordinate*)malloc(sizeof(Coordinate)*(myListLength+1));
    for(i=0; i < myListLength; ++i) {
        newList[i] = myList[i];
    }
    newList[myListLength].x = x;
    newList[myListLength].y = y;
    if(myList)
        free(myList);
    myList = newList;
    ++myListLength;
 }

请注意,如果可以的话,使用std :: vector会更好。