interesting problem with map<char*, int> [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
char* a = "aaa";
map<char*, int> m;
m.insert(pair<char*, int>(a,5));
a[0] = 'c';
a[1] = 'c';
a[2] = 'c';
cout << a << endl; // a = `ccc`
cout << m["aaa"] << endl; // found the node by `aaa`,
cout << m.begin()->first << endl; // but the node's left is actually `ccc`?
So the node's left is ccc or aaa?

Actually it does not found the node by "aaa" nor "ccc", it founds the node by the memory address a points to. Comparison between pointers does just that, it does not perform a string comparison. If you want to index by a string, then use an std::string.

I didn't understand the question properly. Still, there are few things in your code I would like to comment on, such as:
char* a = "aaa";
This is deprecated. Didn't your compiler give warning message? It should be written as:
const char* a = "aaa";
a[0] = 'c'; //it should be an error if you correctly declare `a`
a[1] = 'c'; //it should be an error if you correctly declare `a`
a[2] = 'c'; //it should be an error if you correctly declare `a`
It's precisely because you shouldn't do this, the declaraton of a in your code is deprecated. If you declare a as I suggested (which is correct also), then the compiler would give error for the above assignment statements.
Moreover, if a is const char*, then your question "the node's left is ccc or aaa?" wouldn't arise in the first place. Because a is after all points to const data, and so you cannot change it, thus m.begin()->first will always be aaa.
Also, the map declaration should be:
map<const char*, int> m;
Or even better would be this:
map<std::string, int> m;

The type of the string literal "aaa" is const char[4]. Despite the type of a being char* (pointer to modifiable char), you've made it point to a read-only memory location.
The line a[0] = 'c'; invokes undefined behavior and, on most compilers, a runtime failure.
Your compiler, apparently, permitted your program to modify the value of the literal "aaa" in this manner, so that the values "ccc" were stored at its memory location. However, when you asked the compiler to generate a pointer to "aaa" again later on, it produced the same address of what it thought was the string "aaa" in its static data section,

Related

manipulating items in a vector within a struct [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I feel so lost trying to figure this out. I have my own data structure that I am planning on using vectors to avoid having to keep track of free space and reorginization that I would need to do if I used a simple array. I don't don't know if I'm just not initializing properly or what, but every assignment I do seems to just disappear into thin air.
Here is some simple code to illustrate what I'm talking about:
#include <vector>
#include <iostream>
using namespace std;
struct node
{
int test_int;
bool test_bool;
};
struct file
{
vector<node> test_file;
};
int main()
{
file myfile;
int myint;
cout << "Enter number: ";
cin >> myint;
myfile.test_file[0].test_int = myint;
cout << "Number entered is: " << myfile.test_file[0].test_int << endl;
return 0;
}
So basically it is a vector inside a struct. It seems that the normal ways to access a vector don't seem to work, as in I can't read or write anything to the vector however things like myfile.test_file.size() seem to work (as in they return a '0' from a freshly created struct). Trying to access the index directly by myfile.test_file[0].test_int results in a runtime error of vector subscript out of range as if it isn't actually there.
Am I not initializing it properly? This seems kind of ridiculous to me and I can't understand why it wouldn't work that way.
Edit:
Edited code to more clearly show behavior I'm referring to. This compiles but gives a runtime error vector subscript out of range
The edited version doesn't work because you're accessing an element past the end of the vector:
myfile.test_file[0].test_int = myint;
Before you can do this, you need to either resize() the vector, or add an element using push_back():
myfile.test_file.push_back(node());
myfile.test_file[0].test_int = myint;

std::string optimization? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Someone want to explain me which code is faster ? and what is the best way to optimise a string assignment ?
code 1 :
std::string result;
int main()
{
for(int i=0;i<1000;i++)
{
/*some code*/
result = stringVar;
/* some code using result */
}
}
code 2 :
int main()
{
for(int i=0;i<1000;i++)
{
/*some code*/
std::string result = stringVar;
/* some code using result */
}
}
And to assigne value :
std::string var;
var.assign("value");
//or
var="value";
And it's possible to release memory used by the value before to add a new one ?
Thank if you can help me to understand that :)
In the case of:
for (...)
std::string result = blah;
the compiler must construct and destruct result each time through the for loop, probably requiring heap allocation and deallocation calls.
In the case of:
std::string result;
for (...)
result = blah;
the string implementation might be able to optimize some heap allocation and deallocation away by only reallocation when blah is to big to fit in result's current buffer.
var=x and var.assign(x) should result in the same code; I would not expect a substantial difference either way.
The first is probably somewhat faster, because it can re-use the allocated memory from the previous pass; the second one destroys the string at the end of each pass through the loop, so frees the storage for the content of the string. An optimizer that keeps the object around, despite it being defined in the loop body, is violating the language rules.
In Code 1, operator= will be called, this is usually implemented by creating a temp object (using copy constructor) and then swapping the guts of the temp object with the lhs object. So a copy constructor, a swap, and a delete of the temp object (when the method operator=() exits) is done in code 1.
In Code 2, a copy constructor is called, and finally the object will be deleted when the for loop pass ends.
So Code 1 has the extra step of swapping the guts of the string class. Although the implementation of operator= might be not as described above for some string libs and so the best advise is to test it for your environment.

What does random_ints(a,N) do and how do I use it in my code? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
http://developer.download.nvidia.com/CUDA/training/GTC_Express_Sarah_Tariq_June2011.pdf
In the above tutorial (slide 29), they initiate 3 pointers to ints:
int *a, *b, *c;
Clearly this is of type (int *), yet they somehow make it possible for the kernel to access its indices with syntax a[index]
They also use some (to me) unknown command to initialize their values:
a = (int *)malloc(size); random_ints(a, N);
So what does this command do? First it casts the pointer *a to point to an int (but later on a magically becomes a vector). I can't find any sources on what random_ints precisely does (and my compiler doesn't recognize it either because it probably requires some include). I guess it makes a a vector of length N with random ints (though a is of type int).
I tried working around this by doing the same thing with vector <int> * a; etc etc but I still have trouble passing that to my kernel (it won't add the elements no matter what I try).
I'm working in C++. Thanks in advance.
Edit: could this be pseudocode? Because the explicit C++ example does this in a different (comprehensible way)
You can use pointer in C/C++ in the way like normal array. See:
Example
int* p = new int[2];
p[1] = 2;
*(p + 1) = 2; // same as line above - just other syntax
*(1 + p) = 2; // and other way
1[p] = 2; // don't use it - but still valid
You can allocate memory by malloc in C++ (it is derived from C way) but only for POD types, like int
Example
int* p = (int*)malloc(12 * sizeof(int)); // C way equivalent to C++: new int [12]
Be aware that you must free this pointer by free(p), not by delete [] p.
I guess the implementation of this function is just assigning N random numbers to int array represented by pointer:
Example:
void random_ints(int* a, int N)
{
int i;
for (i = 0; i < N; ++i)
a[i] = rand();
}

c++ delete pointer issue, can still access data [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I don't really understand why are those pointer accessible ... any help appreciated
#include <iostream>
class Wicked{
public:
Wicked() {};
virtual ~Wicked() {};
int a;
int b;
};
class Test
{
public:
Test() {};
virtual ~Test() {};
int c;
Wicked * TestFunc()
{
Wicked * z;
c = 9;
z = new Wicked;
z->a = 1;
z->b = 5;
return z;
};
};
int main()
{
Wicked *z;
Test *t = new Test();
z = t->TestFunc();
delete z;
delete t;
// why can I set 'z' when pointer is already destroyed?
z->a = 10;
// why does z->a print 10?
std::cout << z->a << std::endl;
// why does t->c exist and print correct value?
std::cout << t->c << std::endl;
//------------------------------------------------------
int * p = new int;
*p = 4;
// this prints '4' as expected
std::cout << *p << std::endl;
delete p;
// this prints memory address as expected
std::cout << *p << std::endl;
return 0;
}
Deleting a pointer doesn't zero out any memory because to do so would take CPU cycles and that's not what C++ is about. What you have there is a dangling pointer, and potentially a subtle error. Code like this can sometimes work for years only to crash at some point in the future when some minor change is made somewhere else in the program.
This is a good reason why you should NULL out pointers when you've deleted the memory they point to, that way you'll get an immediate error if you try to dereference the pointer. It's also sometimes a good idea to clear the memory pointed to using a function like memset(). This is particularly true if the memory pointed to contains something confidential (e.g. a plaintext password) which you don't want other, possibly user facing, parts of your program from having access to.
That's undefined behaviour. Anything can happen.You were lucky this time. Or perhaps unlucky since it would be preferable to get a runtime error! Next time round maybe you'll get a runtime error.
It's not really very useful to reason about why you see a particular manifestation of undefined behaviour. It's best to stick to the well-defined behaviour about which you can reason.
C++ won't stop you from writing to an arbitrary location in memory. When you allocate memory with new or malloc, C++ finds some unused space in memory, marks it as allocated (so that it doesn't accidentally get handed out again), and gives you its address.
Once you delete that memory however, C++ marks it as free and may hand it out to anyone that asks for it. You can still write to it and read from it, but at this point, someone else might be using it. When you write to that place in memory, you may be overwriting some value you have allocated elsewhere.
Here
// why can I set 'z' when pointer is already destroyed?
z->a = 10;
z still points at a memory location.
But it no longer blongs to you. You have passed it to delete and said take care of this pointer. What it does is no longer your concern. Its like when you sell your car; it still exists but its not yours so opening the door and looking in may be possible, but it may result in the police arresting you.
Same with deleted pointers the memory exists but does not belong to you.
If you look inside it may work, but it may also cause a segmentation fault as the library has flushed the page (you never know).
delete z; just deallocates the memory z was pointing to, it does not destroy the pointer itself.
So z becomes a wild pointer.
Because deleting a block of memory does not zero the value of all pointers that point to it. Deleting memory merely makes a note that the memory is available to be allocated for some other purpose. Until that happens, the memory may appear to be intact -- but you can't count on it, and on some compiler/runtime/architecture combinations, your program will behave differently -- it may even crash.

please tell me whats wrong in this code [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
#include <iostream>
using namespace std;
int main()
{
char *fp = "Alex";
cout<<fp <<" "<<(void*)fp<<endl;
*(fp+1) = 'p';
cout<<fp <<" "<<(void*)fp<<endl;
}
You modified a string literal. That's undefined behavior.
Increase the warning level on your compiler, you want a warning/error for the line char *fp = "Alex";, because it creates a non-const pointer to immutable data. It's only allowed in C++ for compatibility with C, and it's a misfeature there too.
I don't really like answering "questions" like this, but here is an obvious error:
*(fp+1) = 'p';
fp points to readonly memory as you assigned a string literal to it. Thus, you cannot modify what fp points to. If you want to modify the string declare fp as a char[] so that it will be allocated on the stack.
I'm going to have to assume that you are talking about the following compiler warning:
prog.cpp: In function ‘int main()’:
prog.cpp:5: warning: deprecated conversion from string constant to ‘char*’
Next time please tell us in the question why it is that you think something is "wrong".
As the warning states, converting string constants to char*, whilst fairly normal in C, is deprecated in C++.
Do this instead:
#include <iostream>
using namespace std;
int main() {
char const *fp = "Alex"; // <--- `const` here
cout<<fp <<" "<<(void*)fp<<endl;
*(fp+1) = 'p';
cout<<fp <<" "<<(void*)fp<<endl;
}
You will then find that your statement *(fp+1) = 'p' does not compile. That is because of the const; in fact, the lack of const in your original code merely hid the fact that you may not modify the underlying data of that string literal.
You should copy the characters to a new buffer that your program owns. You can do this neatly using std::string:
#include <iostream>
#include <string>
using namespace std;
int main() {
string fp = "Alex";
cout << fp << " ";
fp[1] = 'p';
cout << fp << " ";
}
In general, use std::string wherever you can. There is rarely a reason to avoid the features of the C++ Standard Library.