标签: memory-management

将`char*`与`delete`解除分配 - 内存泄漏?

template<typename T> char* allocateSomething()
{
    return reinterpret_cast<char*>(std::allocator<T>{}.allocate(1));
}

void deallocateSomething(char* mPtr) { delete mPtr; }

struct TestType { ... };

int main()
{
    char* ptr{allocateSomething<TestType>()};
    deallocateSomething(ptr);   
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否可以保证deallocateSomething(ptr)释放所有已分配的字节,即使它typename T在调用时不知道使用的是什么allocateSomething<T>()

还是有必要模板化deallocateSomething

编辑:我手动处理对象的构造/销毁.


编辑2:这会正常工作吗?

template<typename T> char* allocateSomething()
{
    return reinterpret_cast<char*>(std::malloc(sizeof(T)));
}

void deallocateSomething(char* mPtr) { std::free(mPtr); }

// ...
Run Code Online (Sandbox Code Playgroud)

c++ memory memory-management c++11

-2
推荐指数
1
解决办法
208
查看次数

在C++中删除新结构

我在C++代码中有错误的行为,似乎是由于动态创建的结构的错误释放造成的.结构形式如下:

typedef struct
{
    char *value;
} Element;

typedef struct
{
    int num;
    Element **elements;
    int *index;
} Container;
Run Code Online (Sandbox Code Playgroud)

它们是这样创建的:

Element *new_element(int size)
{
    Element *elem = new Element;
    elem->value = new char[size];
    return elem;
}

Container *new_container(int num)
{
    Container *cont = new Container;
    cont->num = num;
    cont->elements = new Element*[num];
    cont->index = new int[num];
}
Run Code Online (Sandbox Code Playgroud)

解冻这些的正确方法是什么?

c++ free struct memory-management delete-operator

-2
推荐指数
1
解决办法
89
查看次数

为什么没有给另一个进程访问内存位置?

我有三个C代码.在第一个代码c0.c中,整数指针(p)是动态分配的存储器,用于保存一个整数值.值325被分配给该指针变量(p)指向的内存.该指针的整数值存储在一个文件中.在不释放内存的情况下,该指针变量(p)被赋予NULL值.然后将整数值再次读入长变量(i),并为指针变量(p)分配该变量(i)的(int*)值.取消引用并打印时,它会输出值325.代码如下所示.

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int *p = (int*)malloc(sizeof(int));
  *p = 325;

  FILE *F;
  F = fopen("xxx", "w");
  fprintf(F, "%ld", (long)p);
  fclose(F);

  p = NULL;

  long i;
  F = fopen("xxx", "r");
  fscanf(F, "%ld", &i);
  p = (int*)i;
  fclose(F);

  printf("value stored in read pointer = %d\n", *p);

  return(0);
}
Run Code Online (Sandbox Code Playgroud)

现在使用两个单独的文件c1.c和c2.c尝试相同的事情.在c1.c中,指针p被分配了存储器,值325被存储在它指向的存储器中.指针的整数值存储在一个文件中,程序执行由scanf暂停.在c2.c中,读取指针的整数值并将其分配给另一个整数指针.取消引用此指针变量,并尝试打印该值.预计产量为325.因此,当c1.c被编译并运行并且暂停时,将运行c2.c的已编译可执行文件.它崩溃了.为什么?

c1.c和c2.c如下.

c1.c:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int *p = (int*)malloc(sizeof(int));
  *p = 325;

  FILE *F;
  F = fopen("xxx", "w");
  fprintf(F, "%ld", (long)p);
  fclose(F);

  int j; …
Run Code Online (Sandbox Code Playgroud)

c c++ memory-management

-2
推荐指数
1
解决办法
431
查看次数

vector clear()似乎没有释放push_back中分配的内存

这是一个简单的程序,我尝试用向量来理解内存分配/自由行为.struct有一个vector<int>as成员.我的理解是clear()对向量的调用将导致向量元素的内存不受影响.但是valgrind标记了内存泄漏.

代码看起来很简单,但是花了很长时间才来到这里.

#include <iostream>
#include <vector>

using namespace std;

struct a {
    vector<int> v;
};

int main (void) {

    struct a *aptr = (struct a*) calloc(1, sizeof(struct a));

    aptr->v.push_back(10);

    aptr->v.clear();

    free(aptr);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)
==27649== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==27649==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27649==    by 0x4013A7: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (new_allocator.h:92)
==27649==    by 0x4011BE: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (in /homes/dineshb/code_tryout/c++/vectors/a.out)
==27649==    by …
Run Code Online (Sandbox Code Playgroud)

c++ memory-management vector

-2
推荐指数
1
解决办法
520
查看次数

堆内存损坏

int main()
{
    char *p = new char[100];
    strcpy(p, "Test");
    cout << "Before heap corruption: " << p << endl;
    p[150] = '\0';

    cout << "after heap corruption: " << p;

    delete p;

    getchar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面提到的代码中,我在一个不是我的内存位置写'\ 0',即使这样也没有抛出异常.如果使用注释delete p运行上面的代码,则不会抛出任何异常.但是如果它被取消注释,则抛出附加的异常.因此,删除可验证内存所有权.那么,我是否可以知道eaxctly删除是如何工作的以及为什么在写出内存块时有很多验证

在此输入图像描述

c++ windows heap memory-management

-2
推荐指数
1
解决办法
542
查看次数

C如何保护指针内存?

鉴于:

int a = 1;
int *p = &a;
int b = -1;
*++p = 2;
Run Code Online (Sandbox Code Playgroud)

是否存在阻止b从-1写入2的任何事情,如果在明显不可能的事件中,两个a和b在内存中彼此相邻写入?

c memory pointers memory-management

-2
推荐指数
2
解决办法
735
查看次数

为什么这个内存引用了segfault?

double fun(int i)
{
 volatile double d[1] = {3.14};
 volatile long int a[2];
 a[i] = 1073741824;
 return d[0];
}
Run Code Online (Sandbox Code Playgroud)

有趣(0)➙3.14

有趣的(1)➙3.14

有趣的(2)➙3.1399998664856

有趣的(3)➙2.00000061035156

好玩(4)➙3.14,然后分段错误

谁可以向我解释在这个例子中发生了什么以及为什么在调用func(2)时段错不会出现?为什么返回值不总是3.14?

c memory-management

-2
推荐指数
1
解决办法
65
查看次数

C malloc和免费

我被教导如果你做malloc(),但你没有free(),内存将一直保持到重新启动.好吧,我当然测试了它.一个非常简单的代码:

#include <stdlib.h>

int main(void)
{
    while (1) malloc(1000);
}
Run Code Online (Sandbox Code Playgroud)

我在任务管理器(Windows 8.1)中查看了它.

嗯,该程序真的很快就占用了2037.4 MB而且就这样.我知道它可能是Windows限制程序.

但这是奇怪的部分:当我关闭控制台时,内存使用百分比下降,即使我被教导它不应该!

免费呼叫是多余的,因为操作系统无论如何都要释放它?

(这里的问题是相关的,但不能完全回答我是否应该自由.)

c malloc free memory-management

-2
推荐指数
1
解决办法
272
查看次数

按值返回std :: string是否安全?

在以下代码中,字符串封装在类Foo中.

对Foo :: getText()的调用按值返回字符串.这将创建字符串对象的第二个实例,但现在两个字符串对象都指向堆上的相同char缓冲区.

删除Foo实例时,将自动销毁封装的字符串,因此将删除堆上的char缓冲区.

即使getText()按值返回字符串,生成的字符串对象仍依赖于原始字符串对象的生命周期,以便保留它们相互指向的char缓冲区.

这是不是意味着打印retval到终端是对堆已经免费的内存的无效访问?

class Foo
{
    Foo(const char* text) :
       str(text)
    {
    }

    std::string getText()
    {
        return str;
    }

    std::string str;
};

int main()
{
    Foo pFoo = new Foo("text");
    std::string retval = foo.getText();
    delete pFoo;
    cout << retval;  // invalid memory access to char buffer?
}
Run Code Online (Sandbox Code Playgroud)

我想很多人都认为,因为字符串是按值返回的,所以不需要关心Foo中原始字符串的生命周期.这个问题与字符串没有严格的关系,但实际上适用于任何具有封装指针的类,这些指针在销毁时是免费的.但是在弦乐方面,最好的做法是什么?

  1. 永远不要按值返回字符串?
  2. 如果保证原始字符串的生命周期,只按值返回字符串?
  3. 总是复制一下这个字符串? return std::string(retval.c_str());
  4. 与来电者签订合同getText()

编辑:

我想我被RVO误导了.此示例中的所有三个字符串都在同一地址返回c_str.RVO应该受到指责吗?

class Obj
{
public:
    Obj() : s("text")
    {
        std::printf("%p\n", s.c_str());
    }

    std::string getText() { …
Run Code Online (Sandbox Code Playgroud)

c++ string memory-management return-by-value

-2
推荐指数
2
解决办法
1639
查看次数

为什么我需要在C#中实例化一个对象,而不是在C++中为了访问一个类的函数?

我最近开始用C#编写Unity(游戏引擎)开发.我注意到与C++不同; C#要求我在使用其成员函数或变量之前在堆上实例化一个对象.与C++一样,我可以声明一个对象并从声明名称中调用任何函数.

C++示例:

#include <iostream>
using namespace std;
class SampleClass 

{
   void PrintFunc()
   {
      cout<<"Hello World"<<endl;
   }
 }

int main()
{

   SampleClass objectC; //Object declaration
   objectC.PrintFunc(); //Use of function without instantiation

   //The above code will print'Hello World'
}
Run Code Online (Sandbox Code Playgroud)

C#示例:

 using System

 namespace ConsoleProject2
{
    class MainClass
   {

   class SampleClass
   {
        Void PrintFunc()
        {
          Console.WriteLine("Hello World");
        }
    }

    public static void Main (string[] args)
    {

        SampleClass objectC = new SampleClass();
        //Must instantiate before accessing member functions 
        objectC.PrintFunc(); //Prints out 'Hello World' …
Run Code Online (Sandbox Code Playgroud)

c# c++ memory memory-management

-2
推荐指数
1
解决办法
371
查看次数