带有map C++程序没有提供与上次存储相同的资源
C++ program with map is not giving same resutls as it stored last time
我有以下程序,它在map中存储四个字符串并首次打印。现在它运行另一个时间来检索存储的值。但第二次结果与第一次结果不同。
#include <map>
using namespace std;
void fun_call(void **,char * );
main(){
void *data=NULL;
char value[100];
int i=0,j=0;
char key[][10]={"disk1","disk2","disk3","disk4"};
cout << "printing all mapped values " << endl ;
data = (void *) malloc( 100);
for(j=0;j<2;j++){
for(i=0;i<4;i++){
fun_call(&data,key[i]);
memcpy(value,data,100);
cout << "key ="<<key[i]<<" value is " << value << endl;
}
cout <<"====================="<< endl;
}
}
void fun_call(void **tmp,char name[10])
{
void *tmp_data;
char str[100]="ravindra";
int len =0;
static std::map<std::string,void *> name_data_map;
std::map<std::string,void *>::iterator iter ;
iter=name_data_map.find(name) ;
if ( iter == name_data_map.end())
{
len=strlen(str)+strlen(name)+1;
tmp_data = (void *) malloc ( len );
strcat(str,name);
memcpy(tmp_data,str,len);
name_data_map[name]=tmp_data;
cout << "Inside the if" << endl ;
}
else
cout << "disk pos "<< iter->first << endl;
cout << "Outside the if" << endl ;
iter=name_data_map.find(name) ;
memcpy(*tmp,iter->second,len);
}
输出:
$ ./a.out打印所有映射值在如果在如果之外键 =磁盘 1 值是 Ravindradisk1在如果在如果之外键 =磁盘 2 值是 Ravindradisk2在如果在如果之外键 =磁盘 3 值是 Ravindradisk3在如果在如果之外键 =磁盘 4 值是 Ravindradisk4=====================磁盘 POS 磁盘 1在如果之外键 =磁盘 1 值是 Ravindradisk4磁盘 POS 磁盘2在如果之外键 =磁盘 2 值是 Ravindradisk4磁盘 POS 磁盘3在如果之外键 =磁盘3 值是 Ravindradisk4磁盘 POS 磁盘4在如果之外键 =磁盘 4 值是 Ravindradisk4
知道为什么第二次迭代将所有数据都作为:"Ravindradisk4"
len
在fun_call
开头设置为 0,所以如果在第二次运行中它没有进入你的if
,memcpy
最后复制 0 字节。因此,无论key
如何,第一次迭代中main()
的最后一个value
都保持不变。
你的代码有很多问题,如果它是一个有效的(或远程习惯的)C++程序。
正如@starbugs指出的那样,您第二次没有使用正确的长度来复制结果。 一行"修复"将是更改:
memcpy(*tmp,iter->second,len);
。自:
memcpy(*tmp,iter->second,strlen((char*)iter->second)+1);
对于为什么脆性 C 字符串技术最好用C++方法代替的一些基础知识,我想向人们展示以下内容:
学习标准C++作为一门新语言 (PDF) by Bjarne
一旦你掌握了你可能更能接受C++和标准库应该使用的精神。
您的程序是如此琐碎,以至于很容易展示如何简化它以生成更健壮且易于阅读的惯用代码:
#include <map>
#include <iostream>
#include <string>
using namespace std;
string fun_call(string name)
{
static map<string,string> name_data_map;
map<string,string>::iterator iter;
iter = name_data_map.find(name);
if (iter == name_data_map.end()) {
string mapvalue = "ravindra";
mapvalue += name;
name_data_map[name] = mapvalue;
cout << "Inside the if" << endl ;
}
else
cout << "disk pos "<< iter->first << endl;
cout << "Outside the if" << endl;
iter = name_data_map.find(name) ;
return iter->second;
}
int main() {
string keys[] = {"disk1","disk2","disk3","disk4"};
cout << "printing all mapped values " << endl ;
for(int j = 0; j < 2; j++) {
for(int i = 0; i < 4; i++){
string value = fun_call(keys[i]);
cout << "key =" << keys[i] <<" value is " << value << endl;
}
cout << "=====================" << endl;
}
}
我将停止提供一个具有相同输出和控制流的基本等效程序。
笔记:
在标准C++中,main 必须有一个 int 作为返回类型(尽管它不需要参数或 return 语句,奇怪的是)
using namespace std;
行使您不必在标准库类(如字符串、map 及其迭代器)前面键入std::
。 但是不要把它放在头文件中,因为它可能会导致包含它们的其他源文件出现问题,并且有自己的定义,如果不消除歧义,这些定义可能会与标准名称冲突。如果使用标准库,则值类型在后台进行内存管理,并且它们使用的内存在类内分配并在析构函数中释放。 如果您需要执行显式内存管理,请使用 new 和 delete。
首先,一般来说,C++
考虑使用 new
/delete
而不是 malloc()
/free()
.
我不确定你到底想完成什么(即为什么你不断地复制值),但你没有设置长度,所以memcpy()
不会复制任何东西。
解决此问题的另一个简单方法是使用存储在iter->second
中的指针(请注意,您可以修改data
并更新该映射条目 - 所以也许这不是您想要的)。
例如,不要在 main 中为 data
变量分配内存,只需更改此行
memcpy(*tmp, iter->second, len);
自
*tmp = iter->second;
现在,main 中 data
的指针地址设置为存储在地图中的指针地址。
首先,我什至不确定你的代码是如何编译的。您的主函数缺少返回类型,void/不返回只是不好的做法。重构它以适应简单的返回 0 并使其返回类型int
。
此外,在编译之前缺少几个包含(即 iostream 和字符串)。不要使用 using namespace std
,尝试仅从 std 命名空间中"提取"您需要的内容。一般来说,将其全部引入是一种潜在的危险和不良做法,因为将来您可能会遇到命名约定冲突(这将带来很多麻烦)。
回到手头的问题。如果你不是在试验/惩罚你的思想,你就会在这里应用一些非常糟糕的做法。如此多的内存复制和指针移动,即使在我处理移动顶点缓冲区时,我也无法完成。并将您的分配与释放分配相匹配,这是一些非常糟糕的内存管理。在C++中,我们使用new/delete。
由于您要将指针的地址传递给数据变量,因此只需使用 *tmp 修改数据的指针即可。
由于您的name_data_map是静态的,因此它可以在循环中幸存下来。因此,iter
的第二个数据成员是指向当前数据对象的实际指针。只需更改第二个函数的最后一行代码:
*tmp = iter->second;
无论如何,这是我的两分钱...我什至不明白你想做什么。祝你好运!
- 具有瞬态资源的RAII类
- 将字符串存储在c++中的稳定内存中
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 使用QProcess执行命令,并将结果存储在QStringList中
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 允许从 std::map 的密钥窃取资源?
- 从存储为 Windows 资源 (c++) 的 png 中获取 png 文件数据
- QT;我如何在运行时存储通往变量的资源路径
- 如何将数据存储在C 可执行文件的资源部分中
- C++/CLI 存储过程找不到资源
- 带有map C++程序没有提供与上次存储相同的资源
- 存储资源的最有效方式
- C++:存储复制操作不合理或不可能的资源
- 在linux上为C++程序存储资源的位置
- 使用Win32 API列出存储在资源专用库(DLL)中的消息id和符号名称
- OpenGL/ c++将所有纹理资源作为静态成员存储在一个单独的类中
- 以原子方式访问存储在映射中的资源