跨文件调用Paquetes类GenerarID方法无输出问题排查
问题分析与解决方案
核心错误点
1. main函数中的致命逻辑错误
- 你先调用
free(codeID);释放了内存,之后尝试输出codigo,这里存在两个问题:codigo是未定义的变量,实际要输出的是codeID- 内存释放后指针变为野指针,访问它属于未定义行为,必然无法输出正确内容
- 正确顺序应为先输出内容,再释放内存
2. 类成员变量与全局变量混淆
- Paquetes类中声明了成员变量
int counter;,但你在cpp文件中定义了全局的int counter = 0;,二者是完全独立的变量 - GenerarID函数中使用的
cont++;里,cont从未定义,属于编译错误,应该使用类的成员变量counter,并在构造函数中初始化它为0
3. C风格字符串缺少终止符
- 生成的ID是7个字符,但C语言字符串必须以
'\0'结尾才能被正确识别 char ID[7];和malloc(7 * sizeof(char))都只分配7字节,没有空间存储终止符,strcpy时会越界复制,导致输出异常
4. rand()未初始化随机种子
- 直接调用
rand()会每次运行生成相同的随机序列,需要在程序启动时调用srand(time(NULL))初始化随机种子
5. 头文件中的冗余代码
- Paquetes.h文件末尾的ID赋值、malloc等代码属于错误粘贴,必须删除,否则会导致编译失败
修正后的代码
Paquetes.h
#ifndef PAQUETES_H #define PAQUETES_H #define N1 100 struct CoordenadasGPS { char latitud[10]; char longitud[10]; }; struct Etiqueta{ char codigoID[8]; // 预留终止符空间 struct CoordenadasGPS coordenadas; char DNI[9]; }; struct Paquete{ struct Etiqueta informacion; Paquete *siguiente; }; class Paquetes{ public: Paquetes(); virtual ~Paquetes(); int counter; char * GenerarID(); protected: private: }; #endif // PAQUETES_H
Paquetes.cpp
#include "Paquetes.h" #include <iostream> #include <cstdio> #include <locale.h> #include <cstdlib> #include <ctime> #include <cstring> using std::cout; using std::cin; using std::endl; Paquetes::Paquetes() : counter(0) { srand(time(NULL)); // 初始化随机种子 } Paquetes::~Paquetes(){ //dtor } char* Paquetes::GenerarID(){ char ID[8]; // 多1字节存终止符 char letter[] = "abcdefghijklmnopqrstuvwxyz"; char numbers[] = "0123456789"; int num1, num2, num3, num4; int contaux = counter; counter++; // 使用类成员变量计数 num1 = contaux / 1000; contaux -= num1 * 1000; num2 = contaux / 100; contaux -= num2 * 100; num3 = contaux / 10; contaux -= num3 * 10; num4 = contaux; ID[0] = numbers[rand() % 10]; ID[1] = numbers[rand() % 10]; ID[2] = letter[rand() % 26]; ID[3] = numbers[num1]; ID[4] = numbers[num2]; ID[5] = numbers[num3]; ID[6] = numbers[num4]; ID[7] = '\0'; // 添加字符串终止符 char *str = (char*)malloc(8 * sizeof(char)); // 分配8字节空间 strcpy(str, ID); return str; }
Main.cpp
#include <iostream> #include <cstdio> #include <locale.h> #include "Paquetes.h" #include <cstring> using std::cout; using std::cin; using std::endl; int main(){ Paquetes p; char *codeID = p.GenerarID(); cout << codeID << endl; // 先输出ID free(codeID); // 再释放内存 return 0; }
内容的提问来源于stack exchange,提问作者Gonseilo
相关产品推荐
相关产品推荐

