将内存和存储分配到指针中

Posted

技术标签:

【中文标题】将内存和存储分配到指针中【英文标题】:Allocating memory and storage into pointer 【发布时间】:2021-07-11 14:15:10 【问题描述】:

我对 C++ 非常陌生,想问一些关于在 C++ 中分配内存的问题。 抱歉,这似乎是一个基本问题,但下面我有一个使用 malloc 分配的内存地址。 Malloc 使用整数大小的倍数,这将返回一个 void 指针,但随后将其转换为整数指针。如果从技术上讲,它实际上不是指向整数大小的内存区域,而是整数大小的内存的倍数,为什么允许分配给整数?

#include <stdio.h>
#include <stdlib.h>
int main() 
   int n = 4, i, *p, s = 0;
   p = (int*) malloc(n * sizeof(int));
   if(p == NULL) 
      printf("\nError! memory not allocated.");
      exit(0);
   
   printf("\nEnter elements of array : ");
   for(i = 0; i < n; ++i) 
      scanf("%d", p + i);
      s += *(p + i);
   
   printf("\nSum : %d", s);
   return 0;

【问题讨论】:

在 C++ 中,没有理由使用mallocfree,只有newdelete。您确定要学习 C++ 而不是 C,这是一种完全不同的语言吗?你用的是什么教科书,是C还是C++的?而且,如果您真的想学习 C++,那么使用new 的理由并不多。现代 C++ 代码几乎从不这样做,而只是使用 C++ 库中为您正确管理所有内存分配的众多容器之一。 (1) 从不使用malloc/free,(2) 几乎从不使用new/delete;对于上面的代码,请使用std::vector&lt;int&gt; my_vector(n); 请参阅en.cppreference.com/w/cpp/container/vector 您问题中的代码是纯C(不同的语言)。 看来您是从 C 背景进入 C++ 的。在我看来,用 C 的先入之见来学习 C++ 更难。几乎所有好的 C 习惯和编程策略都被认为是 C++ 中的坏习惯或反模式。上面几乎所有的代码都应该是std::vector&lt;int&gt; p(4); 我没有阅读任何教科书,但我正在阅读有关内存对齐的内容,并提出了一个使用 C++ 作为演示的示例。大约 5 年前我学习了 C++,所以只是回来重新审视 C++ 的部分内容以理解示例 @YogiBear 您最好重新标记您的问题C,就像在 C++ 中一样,这不是推荐的代码/编码风格。你很可能会让所有 C++ 人说“不要那样做” 【参考方案1】:

我假设您指的是p = (int*) malloc(n * sizeof(int)); 这一行。

您不是分配给整数,而是分配给整数指针,p 被声明为int* pmalloc 返回一个内存块的地址,在这种情况下 intvoid pointer 可以转换为任何东西,但我们知道它是指向块 int 的指针,这就是为什么有适当的转换。

【讨论】:

【参考方案2】:

从低到高都有优势。

void *p = malloc(n * sizeof int);

原始内存块。没有编译时检查。没有运行时检查。用户可以跟踪类型、大小和生命周期。

int a[n] = malloc(sizeof(a));

整数数组。类型 int 操作的编译时检查。没有运行时检查。用户跟踪使用情况并在完成后释放。

vector <int> a;
a.resize(n);

C++ 整数向量。编译和运行时检查。可动态调整大小。离开作用域时自动删除。

【讨论】:

【参考方案3】:

您正在分配足够的动态内存来保存n 数量的ints 数组,然后您将p 指向该内存中的第一个int。那么你为什么不期望任务成功呢? int* 指针可以指向 int

但是,你真的不应该在 C++ 中使用malloc()(以及scanf()printf())。 C++ 不是 C,它们是不同的语言,有不同的做事方式。在 C++ 中使用 new(以及 std::cinstd::cout):

#include <iostream>

int main() 
    int n = 4, *p, s = 0;
    p = new int[n];
    std::cout << "\nEnter elements of array : ";
    for(int i = 0; i < n; ++i) 
        std::cin >> p[i];
        s += p[i];
    
    delete[] p;
    std::cout << "\nSum : " << s;
    return 0;

或者,在 C++11 及更高版本中,您可以使用 std::unique_ptr 为您处理 delete[](以及 C++14 及更高版本中的 new[]):

#include <iostream>
#include <memory>

int main() 
    int n = 4, s = 0;
    auto p = std::make_unique<int[]>(n); // C++14 and later
    // std::unique_ptr<int[]> p(new int[n]); // C++11
    std::cout << "\nEnter elements of array : ";
    for(int i = 0; i < n; ++i) 
        std::cin >> p[i];
        s += p[i];
    
    std::cout << "\nSum : " << s;
    return 0;

但是,当您需要动态数组时,您应该更喜欢使用标准的std::vector 容器。让它为你处理动态内存的分配和清理:

#include <iostream>
#include <vector>

int main() 
    int n = 4, s = 0;
    std::vector<int> p(n);
    std::cout << "\nEnter elements of array : ";
    for(int i = 0; i < n; ++i) 
        std::cin >> p[i];
        s += p[i];
    
    std::cout << "\nSum : " << s;
    return 0;

尽管在这种特殊情况下,您实际上并没有将数组用于任何有意义的事情,因此您可以完全摆脱数组,单个 int 就足够了:

#include <iostream>

int main() 
    int n = 4, v, s = 0;
    std::cout << "\nEnter elements of array : ";
    for(int i = 0; i < n; ++i) 
        std::cin >> v;
        s += v;
    
    std::cout << "\nSum : " << s;
    return 0;

【讨论】:

你能解释一下两者的区别和优势吗? 如果您提供有关优势的更多详细信息,可以投票

以上是关于将内存和存储分配到指针中的主要内容,如果未能解决你的问题,请参考以下文章

指针数组的动态内存分配

C 语言二级指针作为输入 ( 自定义二级指针内存 | 为 二级指针 分配内存 - 存放 一维指针 | 为每个 一级指针 分配内存 | 释放二维指针内存 )

C++中内存分配问题

声明为指针的每个变量都必须分配内存吗?

c 链表和动态内存分配

5指针