C++带有地图的程序 - 解释下面的程序是如何工作的
C++ program with map - Explain the below program how it's working
在下面的程序中,tmp_data首先打印为:"Ravindra Kumar"。但是在复制到地图后,它被更改为"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR当我们下次打印时,它仍然打印"Ravindra Kumar" - 如何。它应该打印RRRRRRRRRRRRRR对吗?
#include <iostream>
#include <cstring>
#include <string>
#include <map>
using namespace std;
void fun_call( );
main(){
cout << "printing all data " << endl ;
fun_call();
fun_call();
}
void fun_call()
{
// static void *tmp_data;
void *tmp_data;
char *str="Ravindra Kumar";
char *str1="RRRRRRRRRRRRRRRRRRRRR";
char name[]="Ravi";
char value[100];
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())
{
tmp_data = (void *) malloc ( strlen(str)+1 );
memcpy(tmp_data,str,strlen(str)+1);
name_data_map[name]=tmp_data;
cout << "Inside the if" << endl ;
}
cout << "Outside the if" << endl ;
iter=name_data_map.find(name) ;
memcpy(value,iter->second,strlen(str)+1);
cout << "value is " << value << endl ;
tmp_data=(void *)malloc(100000);
memcpy(tmp_data,str1,strlen(str1)+1);
}
输出:
$ ./a.out
printing all data
Inside the if
Outside the if
value is Ravindra Kumar
Outside the if
value is Ravindra Kumar
您将"RRRRRRRRRRRRRRRRRRRRR"
复制到 tmp_data
中,然后退出该函数,完全丢弃tmp_data
(顺便说一句,没有释放它,所以你那里有内存泄漏)。下一次调用 fun_call
将创建一个新的 tmp_data
局部变量,其值与您之前设置的值无关。但是,name_data_map
被声明为 static
,因此它只分配一次(在第一次调用 fun_call
时),然后重用,保留您在上一次调用中放入的值(该值实际上是与您稍后将 R 复制到其中的内存块不同的内存块)。
更新 - 更详细的解释
这里
tmp_data = (void *) malloc ( strlen(str)+1 );
memcpy(tmp_data,str,strlen(str)+1);
name_data_map[name]=tmp_data;
你分配一个内存块,将"Ravindra Kumar"复制到其中,并在地图中存储指向它的指针。此时,name_data_map[name]
和tmp_data
指向同一内存块。从图形上看,它可能大致如下所示(为了简单起见,假设两个文本文本连续存储在内存中,这在现实生活中可能是也可能不是):
name_data_map[name] ----
ˇ
tmp_data ---------------
ˇ
raw memory ..........Ravindra Kumar RRRRRRRRRRRRRRRRRRRRR ............
如果您修改了该内存块的内容(例如,通过将不同的文本复制到tmp_data
中),则更改也将通过name_data_map[name]
可见,因为它们都指向相同的内存位置。
但是,反之亦然:更改地图值后,例如
name_data_map[name]=str1;
程序状态如下所示:
name_data_map[name] --------------------
ˇ
tmp_data ---------------
ˇ
raw memory ..........Ravindra Kumar RRRRRRRRRRRRRRRRRRRRR ............
使两个指针指向不同的位置,因此一个指针的更改不会影响另一个指针。因此,请注意,更改指针的值与更改指针指向的内存值之间存在根本区别。
你完全在几行之后做前者,只是用tmp_data
:
tmp_data=(void *)malloc(100000);
memcpy(tmp_data,str1,strlen(str1)+1);
第一行改变了tmp_data
的值,所以现在它不再指向与name_data_map[name]
相同的位置!之后,无论您对新分配的内存块做什么,它都不会再影响name_data_map[name]
。这就是您未能更改它的原因。
如果我们声明地图为非静态,那么我们可以更改它吗?
错。声明地图static
对此没有影响 - 它只会影响地图的范围。当你退出fun_call
时,非静态映射将不复存在,丢失存储在其中的所有值。当它活着时,您可以更改其值,无论它是否static
。您只需要使用正确的指针即可。
如果您的目标是通过 tmp_data
更改存储在映射中的值,只需删除第二个malloc
并修改第一个以分配更长的块(因为str1
比 str
长,因此尝试将str1
复制到长度为 str
的缓冲区中会导致缓冲区溢出, 即未定义的行为)。之后,您应该有一个有效的 - 虽然令人讨厌 - 代码,因为尝试"背后"修改映射中的值通常不是一个好主意。此外,在C++代码中混合使用C结构(malloc
和原始指针,尤其是void*
)是一个坏主意。如果您只是在试验,这是可以接受的 - 机器人请不要在生产代码中这样做。您的意图有所不同,请澄清。
以下代码更简单,似乎可以执行您想要的操作。 有什么理由更喜欢 char* 而不是 std::string 作为映射中的值吗?
#include <iostream>
#include <string>
#include <map>
void fun_call()
{
const char* str="Ravindra Kumar";
const char* str1="RRRRRRRRRRRRRRRRRRRRR";
const char* name="Ravi";
static std::map<std::string,std::string> name_data_map;
std::map<std::string,std::string>::iterator iter;
iter=name_data_map.find(name) ;
if ( iter == name_data_map.end())
{
name_data_map[name]=str;
cout << "Inside the if" << endl ;
}
cout << "Outside the if" << endl ;
iter=name_data_map.find(name) ;
cout << "value is " << iter->second << endl ;
iter->second = str1;
}
main(){
cout << "printing all data " << endl ;
fun_call();
fun_call();
}
输出:
printing all data
Inside the if
Outside the if
value is Ravindra Kumar
Outside the if
value is RRRRRRRRRRRRRRRRRRRRR
- 如何使实例化在我的 OpenGL 程序中工作?
- 当要求用户输入时,C++程序不工作
- 我的C++程序的工作目录是什么
- 当我尝试输入时程序停止工作
- 将缓冲区转换为在现有程序中工作的iStream
- 请有人解释该程序的工作原理
- 倒计时可以与C ++中的程序同时工作
- 当在函数调用中递增值时,程序正常工作,但是如果我们在单独的行中增加值而不是呼叫函数,则会出现错误.为什么
- CIN 和 COUT 如何在以下程序中工作
- 由于程序停止工作,生成大量数字失败
- 禁用 GPU 使我的 CNTK 程序正常工作.为什么
- 无限循环使程序停止工作
- 该程序如何工作以及为什么答案- (4) C++
- 为什么这是为了使程序停止工作?(C )
- 快速排序程序停止工作
- 以下程序如何工作
- 程序停止工作由 strcat() 与指针
- 只有当我一直显示某些内容直到找到解决方案时,程序才能工作
- 在 Cout << "hello" << endl 中删除 endl 后,我的C++程序停止工作
- 制作大桌子时程序停止工作 (2'000'000+)