-1

我是编程新手,我试图了解两者之间的区别

A = (char * ) malloc(sizeof(char)*n);

A = (char * ) malloc(sizeof(char)); 

或者

A = new char [n];

A = new char;

当我没有指定特定数据类型的对象数量时,编译器分配给该指针的默认内存是多少。

当我宣布

A = new char [n];
cout << A[n+1];

它不会给我一个分段错误。

它应该不会给出分段错误,因为我试图访问超出为数组分配的内存。

4

4 回答 4

5

内存不是“分配给这个指针”,它是分配的,然后你得到一个指向内存的指针。

这个:

char *a = malloc(sizeof(char) * n);

是相同的

char *a = malloc(n);

因为sizeof(char)始终为1。它们都为字符的数据分配空间n并返回指向第一个字符可以访问(或NULL失败时)的位置的指针。

此外,C 不需要演员表,你不应该有。

由于sizeof(char)是 1,第二次调用相当于:

char *a = malloc(1);

这意味着它分配了一个大小为 1 的内存块。这当然不同于指向该内存块的指针(存储在指针变量中的值a)。指针很可能大于 1 个字符,但这不会影响块的大小。

参数malloc()指定要为其分配空间的字符数。

我忽略了new用法,因为那是 C++ 并且问题被标记为 C。

于 2013-10-02T13:08:52.123 回答
2
  • 为字符分配空间N(这里的 N 应该是某个正整数值)

    char *ma = (char * ) malloc(N);
    char *na = new char [N];
    
    • 别忘了释放这段记忆……

      delete [] na;
      free(ma);
      
  • 为单个字符分配空间

    char *mc = (char * ) malloc(sizeof(char)); 
    char *nc = new char;
    

现在,正如其他人所指出的那样,您标记了这个 C,但您的一半代码是 C++。如果您正在编写 C,则不能使用new/ delete,也不需要转换malloc.

哦,读取数组末尾时没有出现分段错误的原因是这是未定义的行为。它肯定导致 SEGV,但不需要检查,因此至少在某些时候可能看起来有效,或者以完全不同的方式失败。

于 2013-10-02T13:16:12.793 回答
2
A = (char * ) malloc(sizeof(char)*n);

这为 n 个字符分配空间。

A = (char * ) malloc(sizeof(char)); 

这为 1 个字符分配内存。

每次调用 malloc 都会在堆中分配内存。

另一个代码是 C++,它完全一样,只是如果 A 是局部变量,它将使用堆栈内存。访问 A[n+1] 可能会也可能不会产生段错误。A[n+1] 可以引用允许使用的内存地址。当您超出可以访问的内存区域时会发生段错误,它的工作方式是存在一个“红色区域”,认为您从中访问了无效内存。可能是 A[n+1] 还不够“无效”来触发段错误。

于 2013-10-02T13:09:58.840 回答
1

好吧,编译器不会为数据分配内存。根据您的体系结构,只有 4 或 8 个字节的指针。

前两个和后两个在功能上没有区别。我见过的大多数 C++ 库在malloc内部用于new.

当您运行代码来分配n字符并打印出第n + 1th 个字符时,您很可能不会遇到分段错误,因为n它不是某个数字的倍数,通常是 8 或 16。这里有一些关于它如何做到这一点的代码:

void* malloc(size_t size) {
    if (size & 0x7 != size)
        size = size & 0x7 + 1;
    return _malloc(size);
}

因此,如果您请求5 个字节,则malloc实际上会使用该代码分配8 个字节。所以,如果你请求第 6 个字节 ( n + 1),你会得到垃圾,但它仍然是你的程序可以访问的有效内存。

于 2013-10-02T13:10:04.043 回答