как работать с указателями и ссылками c ++ и VALGRIND? - PullRequest
0 голосов
/ 23 августа 2011

У меня есть следующий код:

[test.h]
class MyClass
{
public:
    string Name;
    MyClass();
    void method(MyClass &obj);
}

[test.cpp]
void MyClass::method(MyClass &obj)
{
    cout<<obj.Name<<endl;
}

[main.cpp]
#include "test.h"

void main()
{
    MyClass *class = new MyClass();
    class->Name="Foo";
    class->method(*class);

    delete class;
}

Я хотел бы спросить, является ли это правильным способом для метода, который содержит объекты, отправленные по ссылке.Правильно ли я освободил выделенную память?Я спрашиваю об этом, потому что для аналогичного примера при тестировании с помощью valgrind у меня есть следующее: условный переход или перемещение зависимостей по унифицированным значениям.

Я работаю в c ++ под Ubuntu.Мой компилятор g ++.ОЦЕНИВАЕМ !!РЕДАКТИРОВАТЬ !!

ПОЧЕМУ Я НЕ МОГУ ПОСТАВИТЬ INT VALUE = 0;в файле test.h?!

Ответы [ 6 ]

4 голосов
/ 23 августа 2011

class - это зарезервированное слово в C ++, вы не можете использовать его в качестве имени ваших переменных.

Более того, нет необходимости выделять объект динамически, если вы явно не требуете этого.Если возможно, просто выделите его автоматически:

MyClass x;
x.Name = "Foo";
x.method(x);
0 голосов
/ 23 августа 2011

Почему я не могу поставить int VALUE = 0; в файле test.h?

Если VALUE является частью переменных класса, то его нельзя инициализировать как часть объявления класса. Вместо этого следует использовать список инициализатора конструктора.

// Constructor

MyClass :: MyClass() : VALUE(0) 
                  // ^^^^^^^^^^^ Initializer list
{ }

Однако, если VALUE определено как глобальная переменная, это также приводит к проблемам. Когда вы включаете test.h в несколько исходных файлов, это приводит к нескольким ошибкам объявления. Определите его в исходном файле и получите доступ к нескольким переводным единицам, используя ключевое слово extern .

0 голосов
/ 23 августа 2011

Похоже, что нет утечек памяти и использования неинициализированных значений. Name элемент будет инициализирован его конструктором по умолчанию. Ошибки, о которых сообщает Valgrind, могут исходить из стандартной библиотеки или другой библиотеки, которую вы, возможно, использовали. Также обратите внимание, что эта ошибка не всегда указывает на ошибку в коде.

0 голосов
/ 23 августа 2011

это правильно.Единственный способ все испортить - это забыть удаление, удаление более одного раза или несоответствие между новым и удалением с или без скобок.Однако есть несколько вещей, на которые следует обратить внимание:

В вашем примере хорошо передать аргумент как const ref, потому что вы его не меняете.

void method(const MyClass &obj) const;

, а также вcpp соответственно:

void MyClass::method(const MyClass &obj) const{ ... }

Вам не нужно выделять объект в куче, вообще используя new.Фактически, вы почти всегда можете использовать такой синтаксис:

void main()
{
    MyClass obj; // <- allocates it on the stack
    obj.Name="Foo";
    obj.method(obj);
}
// class is properly deleted when it goes out of scope

Всякий раз, когда у вас много необработанных данных, в частности классических массивов, они обычно являются членами класса (и даже это редкий случай из-заклассные контейнеры stl (например, vector), и вы позволите этому классу иметь дело с управлением памятью.Это снова позволяет создавать эти классы в стеке, очищать их, выпуская их из области видимости, и класс позаботится о том, чтобы огромный объем данных фактически хранился в куче.

Так что пока ваш код веренна самом деле вам редко приходится об этом беспокоиться, потому что вы

0 голосов
/ 23 августа 2011

Мне кажется странным, что компилятор не кричал, что class является зарезервированным ключевым словом.

В любом случае, использование method(MyClass &obj), на мой взгляд, не очень хорошая идея, поскольку у вас уже есть указатель,который разыменовывается, а затем снова берется по ссылке.Я просто не знаю, на что оно указывает, и поэтому может появиться предупреждение.

Попробуйте выполнить следующее и посмотрите, есть ли еще те же предупреждения, я не могу проверить это прямо сейчас:

test.h
class MyClass
{
public:
   string Name;
    MyClass();
    void method(MyClass* obj);
}

test.cpp
void MyClass::method(MyClass* obj)
{
    cout<<obj->Name<<endl;
}

main.cpp
#include "test.h"

void main()
{
    MyClass *class = new MyClass();
    class->Name="Foo";
    class->method(class);

    delete class;
}
0 голосов
/ 23 августа 2011

compile => valgrind g ++ ./main и посмотрите, есть ли утечка памяти.

убедитесь, что вы уже установили valgrind, в противном случае вам следует установить его через apt-get или центр программного обеспечения ubuntu.

надеюсь, это поможет ..

...