如何访问指针结构的成员变量?



我已经有一段时间没有用C++编程了,所以我一直在努力改进。我有一个非常简单的登录功能,但它不起作用。login 函数调用getUserAttempts()返回指向包含用户详细信息(如用户名和密码(的结构的指针。但是,每当我尝试访问指针的结构变量时,程序都会崩溃。我觉得我错过了一些明显的东西,但无法将手指放在上面。

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <unordered_map>
typedef std::unordered_map<std::string, std::string> unorderedMap;
typedef struct Credentials {
std::string username;
std::string password;
} structCred;
void login();
structCred* getUserAttempts();

void login() {  
unorderedMap credentialMap;
credentialMap["username"] = "mypassword123";
structCred *p;
for (int i = 0; i < 3; i++) {
p = getUserAttempts();
auto it = credentialMap.find(p->username);
std::cout << it->first;
std::cout << it->second;
}
return;
}

structCred *getUserAttempts() {
structCred credentialAttempt;
std::string username, password;
std::cout << "Please enter your username: ";
std::getline(std::cin, credentialAttempt.username);
std::cout << "Please enter your password: ";
std::getline(std::cin, credentialAttempt.password); 
return &credentialAttempt;
}

int main() {
std::cout << "Welcome..." << std::endl;
login();
return 0;
}
return &credentialAttempt;

这将返回指向函数局部变量credentialAttempt的指针。这是行不通的,因为函数 local 在函数返回时会立即销毁,因此函数返回指向不再存在的内容的指针。因此,取消引用返回的指针是未定义的行为。

相反,只需按值返回对象:

structCred getUserAttempts() {
structCred credentialAttempt;
std::string username, password;
std::cout << "Please enter your username: ";
std::getline(std::cin, credentialAttempt.username);
std::cout << "Please enter your password: ";
std::getline(std::cin, credentialAttempt.password); 
return credentialAttempt;
}

在此函数中:

structCred *getUserAttempts() {
structCred credentialAttempt;
// ...
return &credentialAttempt;
}

您正在将地址返回给一个局部变量,该变量在函数结束时死亡。然后,访问内存是未定义的行为。

相反,您应该为其分配内存:

structCred *getUserAttempts() {
structCred *credentialAttempt = new structCred;
// ...
return credentialAttempt;
}

请注意,像credentialAttempt.username这样的语句必须变得credentialAttempt->username

但是,返回原始指针通常是一个坏主意,因为无法知道释放内存的责任是谁。相反,请使用可以为您释放内存的unique_ptr

std::unique_ptr<structCred> getUserAttempts() {
auto credentialAttempt = make_unique<structCred>();
// ...
return credentialAttempt;
}

最新更新