【问题标题】:Why is a struct member uninitialized after dereferencing the struct为什么取消引用结构后结构成员未初始化
【发布时间】:2015-03-18 10:07:56
【问题描述】:

我正在编写一个HBridge 类,以使处理 HBridges 一个 arduino 变得更加容易。我不确定为什么在我的 HBridge 实例上调用 .print(),它会打印:

---------
BRIDGE ONE
Bridge Use:->pin: 1392293344
Bridge Idle->pin: 1392293408
Freq:0
Dir:0
---------
BRIDGE TWO
Bridge Use:->pin: 8
Bridge Idle->pin: 214125355
Freq:0
Dir:0

注意Bridge UseBridge Idle 是如何未初始化的。我的指针是不是在某个地方出错了?

这是我的代码。

Hbridge.h

//-----------------------|
#define true 1         //|
#define false 0        //|
//-----------------------|
#define PIN_OFF 0      //|
#define PIN_ON  1      //|
//-----------------------|
#define PIN_FORWARD 0 //|
#define PIN_BACKWARD 1//|
//-----------------------|



typedef struct{
    int pin;
} Pin;

typedef struct {
    Pin *inuse;
    Pin *idle;
    int freq;
    int direction;
}Bridge;

typedef enum{ A, B} hbridge_pins;

class HBridge {
    private:
    Bridge bridge_a, bridge_b;
    Bridge *pins[2];
    public:
        HBridge(int, int, int, int);
        void setPinFrequency(hbridge_pins, int);
        void setPinDir(hbridge_pins, int);
        void turnPinOFF(hbridge_pins);
        void update(void);
        void print();
};

Hbridge.cpp

#import "./HBridge.h"
#import <stdio.h>


Pin pinWith(int num) {
    // pinMode(num, OUTPUT);
    Pin p;
    p.pin = num;
    return p;
}

void swap_pins(Pin *a, Pin *b) {
        Pin temp = *a;
        *a = *b;
        *b = temp;
}

void print_pin(const char * name, Pin *p){
    printf("%s->pin: %d\n",name,p->pin);
}
void print_bridge(Bridge *b){
    print_pin("Bridge Use:", b->inuse);
    print_pin("Bridge Idle", b->idle);
    printf("Freq:%d\nDir:%d\n",b->freq,b->direction);

}

void HBridge::turnPinOFF(hbridge_pins pin) {
    pins[pin]->freq = PIN_OFF;
}

HBridge::HBridge(int pinAA, int pinAB, int pinBA, int pinBB) {

    Pin a_use = pinWith(pinAA);
    Pin a_idle = pinWith(pinAB); 
    Pin b_use = pinWith(pinBA);
    Pin b_idle = pinWith(pinBB);


    bridge_a.inuse = &a_use;
    bridge_a.idle = &a_idle;

    bridge_b.inuse = &b_use;
    bridge_b.idle = &b_idle;
    



    /*---(DEFAULT DIRECTIONS)---*/
    bridge_a.direction = PIN_FORWARD;
    bridge_b.direction = PIN_FORWARD;
    bridge_a.freq = PIN_OFF;
    bridge_b.freq = PIN_OFF;
    
    /*---(ARRAY OF POINTERS TO THE TWO PINS FOR EASY ACCESS BY INDEX)---*/
    pins[0] =&bridge_a;
    pins[1] =&bridge_b;
}

void HBridge::setPinFrequency(hbridge_pins pin, int freq) {
    pins[pin]->freq = freq;
}

void HBridge::setPinDir(hbridge_pins pin, int dir) {
    if ((pins[pin]->direction == PIN_FORWARD && dir == PIN_FORWARD) || (pins[pin]->direction == PIN_BACKWARD && dir == PIN_BACKWARD)) {
        
    } else if (pins[pin]->direction == PIN_FORWARD && dir == PIN_BACKWARD) {
        
        /*----(SWAP POINTERS)----*/
        swap_pins(pins[pin]->inuse, pins[pin]->idle);
        pins[pin]->direction = PIN_BACKWARD;
        
    } else if (pins[pin]->direction == PIN_BACKWARD && dir == PIN_FORWARD) {
        
        /*----(SWAP POINTERS)----*/
        swap_pins(pins[pin]->inuse, pins[pin]->idle);
        pins[pin]->direction = PIN_BACKWARD;
        
    }
}

void HBridge::update(void)/*pointer to an int to save memory*/ {
    /*THE FIRST BRIDGE*/
    // analogWrite(pins[0]->inuse->pin, pins[0]->freq);
    // analogWrite(pins[0]->indle->pin, pins[0]->PIN_OFF);

    // THE SECOND BRIDGE
    // analogWrite(pins[1]->inuse->pin, pins[1]->freq);
    // analogWrite(pins[1]->indle->pin, pins[1]->PIN_OFF);
} 

void HBridge::print(void){

    printf("---------\nBRIDGE ONE\n");
    print_bridge(pins[0]);

    printf("---------\nBRIDGE TWO\n");
    print_bridge(pins[1]);
}


int main(int argc, const char*argv[]){
    HBridge b(31,42,33,4);
    b.setPinFrequency(A,200);
    b.print();
}

【问题讨论】:

  • Bridge 应该有一个构造函数来初始化指向nullptr 的指针。
  • 呃!这是 C++ 和 2015 年。为什么是 mallocmemcpy
  • 不要#define真假!它们是语言关键字。
  • 如果你要编写 C++,你需要忘掉你所有的旧 C 习语,比如 typedef struct { } name; 只需做 struct name { }; 停止使用 malloc()。如果您确实需要动态内存,请首选 make_unique() 或 make_shared()。
  • @RobK 感谢您提醒我这一点。我的 C++ 只用了大约 6 个小时,还不太熟悉它的标准库的所有功能。教训:在实施之前,请查看文档以了解传统语言 X 程序员所做的事情。

标签: c++ pointers struct


【解决方案1】:

Pin a_use 是构造函数的本地对象,您正在从中创建一个指针,尽管它会在构造函数返回时被释放。

inuseidle 声明为Pin inuse;Pin idle;,并且不要创建指针,只需将pinWith() 返回的内容分配给它们,值将被复制,问题就会消失。

如果你需要它们是指针,那么首先像这样请求堆空间

bridge_a.inuse = new Pin;

然后这样做

memcpy(bridge_a.inuse, &a_use, sizeof(Pin));

如果Pin 不包含任何类,而只包含POD 字段,它会起作用,否则将需要更详细的副本。

【讨论】:

  • @theideasmith 在HBridge 内部,将Bridge *pins[2]; 更改为Bridge pins[2];(删除指针),然后在构造函数中删除分配给a_usea_idle、@987654336 的和号@,b_idle。如果您必须在print 中获取指针,请传递地址(print(&amp;pin[0]); print(&amp;pin[1]),但您确实应该引用Bridge 并使用. 而不是-&gt;
【解决方案2】:

呼应@iharob。您在pinWith() 函数中遇到同样的问题,您在堆栈中为pinWith() 函数返回一个Pin,一旦您从函数返回,这个位置就会变成“垃圾”。您需要从pinWith() 的堆中分配一个Pin 来解决此问题。

Pin pinWith(int num) {
    // pinMode(num, OUTPUT);
    Pin p = new Pin;
    p.pin = num;
    return p;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2015-02-19
    相关资源
    最近更新 更多