Thread: /= doesn't do what you think it does?

  1. #16
    The larch
    Join Date
    May 2006
    Posts
    3,573
    What I did is use the at method where the index for F comes from an "untrusted" source (in very indirect ways from a map). Try this:

    Code:
    #include <iostream>
    #include <vector>
    #include <map>
    #include <exception>
    using namespace std;
    
    int main(){
        try {
        	vector<vector<float> > kF;
        	vector<float> F;
        	map <int, string> namesmap;
    
        	namesmap[1] = "one";
        	namesmap[2] = "two";
        	namesmap[3] = "three";
        	namesmap[4] = "four";
    
        	vector<map<string,int> > kFmap;
        	kFmap.resize(2);
        	kFmap[0][namesmap[1]] = 5;
        	kFmap[0][namesmap[2]] = 10;
        	kFmap[0][namesmap[3]] = 5;
        	kFmap[0][namesmap[4]] = 20;
    
        	kFmap[1][namesmap[1]] = 5;
        	kFmap[1][namesmap[2]] = 5;
        	kFmap[1][namesmap[3]] = 5;
        	kFmap[1][namesmap[4]] = 20;
    
        	for (unsigned int k = 0; k < 2; k++){
        		cout << "k = " << k << endl;
        		F.resize(6);
        		for (int i = 1; i <= 4; i++){
        			F.at(kFmap[k][namesmap[i]])++;
        		}
        		for (int i = 1; i <= 4; i++){
        			cout << kFmap[k][namesmap[i]] << " kFmap | ";
        			cout << F.at(kFmap[k][namesmap[i]]) << " | ";
        			F.at(kFmap[k][namesmap[i]]) /= (10); //bug
        			cout << F.at(kFmap[k][namesmap[i]]) << " | ";
        			cout << endl;
        		} cout << endl;
        		kF.push_back(F);
        		F.clear();
        	}
        }
        catch (exception& e) {
            cout << e.what() << '\n';
        }
    	return 0;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  2. #17
    Registered User
    Join Date
    Jun 2008
    Posts
    106
    What is the reasoning behind this? Can you tell me about untrusted sources? I'd like to know how this stuff works...

    Edit: that didn't do it for me, I get vector::_M_range_check error. And when I try it in my main program I don't even get that - just the same faulty results!
    Last edited by elninio; 09-21-2008 at 04:58 AM.

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Salem
    If you extract this code, put a minimal support environment around it, and it works, then you can be pretty sure the real problem is somewhere else.
    Indeed, hence the idea is not "to extend it to wider sets", but to use it to determine if the problem is in that portion of code, or likely to be elsewhere.

    Quote Originally Posted by elninio
    What is the reasoning behind this? Can you tell me about untrusted sources? I'd like to know how this stuff works...
    I think anon made the same mistake as me: talking too much

    Here "untrusted" merely means that you cannot be sure that the index provided by the "source" is a valid index for use with the vector. You can either perform a check yourself (compare the index with the vector's size()), or use at() with the index, upon which a std::out_of_range exception will be thrown if the index is invalid (out of range).

    Quote Originally Posted by elninio
    Edit: that didn't do it for me, I get vector::_M_range_check error.
    That means that an exception was thrown, and you are using an index that is out of range (i.e., trying to access the vector out of bounds).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It looks that you are trying to use the values in the map, such as 10 and 20, to index into a vector that has only size 6. Your logic doesn't hold.

    By "untrusted" I meant a value that doesn't come from an obvious place (such as a loop counter) and that isn't validated.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    There's no such thing as C++99. There's C99, which is completely irrevelant to your problem.

    Stop seeking the problem with the compiler. It does not contain bugs that any application that is not extremely complex or irregular will uncover.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Registered User
    Join Date
    Jun 2008
    Posts
    106
    Quote Originally Posted by CornedBee View Post
    There's no such thing as C++99. There's C99, which is completely irrevelant to your problem.

    Stop seeking the problem with the compiler. It does not contain bugs that any application that is not extremely complex or irregular will uncover.
    Not seeking to put blame on the compiler, just hoping that maybe some newer standard could give me a warning about some bad practice which i may be doing that may be contributing to the problem.

  7. #22
    Registered User
    Join Date
    Jun 2008
    Posts
    106
    Quote Originally Posted by anon View Post
    It looks that you are trying to use the values in the map, such as 10 and 20, to index into a vector that has only size 6. Your logic doesn't hold.

    By "untrusted" I meant a value that doesn't come from an obvious place (such as a loop counter) and that isn't validated.
    The size 6 refers to the span of maps, 10 and 20 are INSIDE the map, right?


    vector [ map1 map2 ...]
    5 5
    10 5
    5 5
    20 20

  8. #23
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by elninio View Post
    The size 6 refers to the span of maps, 10 and 20 are INSIDE the map, right?


    vector [ map1 map2 ...]
    5 5
    10 5
    5 5
    20 20
    so kFmap returns 5, 10, and 20 as above, yes. Then you do F[number you just got] -- but F[10] and F[20] don't exist....

  9. #24
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One example of a possible out of bounds access is this:
    Code:
    for (int i = 1; i <= 4; i++){
        F.at(kFmap[k][namesmap[i]])++;
    }
    kFmap only has 2 elements, but you access kFmap[2], kFmap[3] and kFmap[4].
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #25
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by laserlight View Post
    One example of a possible out of bounds access is this:
    Code:
    for (int i = 1; i <= 4; i++){
        F.at(kFmap[k][namesmap[i]])++;
    }
    kFmap only has 2 elements, but you access kFmap[2], kFmap[3] and kFmap[4].
    Yep, it looks to me like that explains the problem too.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #26
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by laserlight View Post
    One example of a possible out of bounds access is this:
    Code:
    for (int i = 1; i <= 4; i++){
        F.at(kFmap[k][namesmap[i]])++;
    }
    kFmap only has 2 elements, but you access kFmap[2], kFmap[3] and kFmap[4].
    And k only looped from zero to one.

  12. #27
    Registered User
    Join Date
    Jun 2008
    Posts
    106
    Quote Originally Posted by laserlight View Post
    One example of a possible out of bounds access is this:
    Code:
    for (int i = 1; i <= 4; i++){
        F.at(kFmap[k][namesmap[i]])++;
    }
    kFmap only has 2 elements, but you access kFmap[2], kFmap[3] and kFmap[4].
    the ith elemeth of kFmap exists. I have two maps of size 4 in it.

    I don't access kFmap[3] and [4] because the k for loop only goes up to 2.

    F.at(kFmap[k][namesmap[i]])++; , namesmap[i] goes up to 4, and that is VALID.

    kFmap[k] goes up to < 2 , and that is also VALID.

  13. #28
    Registered User
    Join Date
    Jun 2008
    Posts
    106
    Quote Originally Posted by tabstop View Post
    And k only looped from zero to one.
    Yes, thats the whole point. kFmap is only defined from 0 to 1. The elements within its map are defined from 1 2 3 4. Valid again.

  14. #29
    Registered User
    Join Date
    Jun 2008
    Posts
    106
    Quote Originally Posted by tabstop View Post
    so kFmap returns 5, 10, and 20 as above, yes. Then you do F[number you just got] -- but F[10] and F[20] don't exist....
    you never access F[10], F increments in terms of k. so only 0 and 1 are accessed. We are accessing the kth element. Look at the K for loop, it only goes to < 2.

  15. #30
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by elninio View Post
    you never access F[10], F increments in terms of k. so only 0 and 1 are accessed. We are accessing the kth element. Look at the K for loop, it only goes to < 2.
    Read your own code:
    Code:
    F.at(kFmap[k][namesmap[i]]) /= (10);
    Let's suppose k is 0 and i is 4.
    Then kFmap[0] is fine, that gets us a map. namesmap[4] is "four". We can then do the mapping -- kFmap[0]["four"] = 20. (You assigned it as kFmap[0][namesmap[4]], but that's fine.) So, the bit inside the at is 20 -- but F.at(20) throws an exception, since F only goes to 5.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  2. This seemed impossible!Can anyone help??
    By nesir in forum C Programming
    Replies: 23
    Last Post: 08-22-2006, 01:23 AM
  3. Replies: 29
    Last Post: 10-25-2005, 09:46 PM
  4. increment/decrement operators
    By ZakkWylde969 in forum C++ Programming
    Replies: 10
    Last Post: 07-10-2003, 04:17 PM
  5. Replies: 11
    Last Post: 03-25-2003, 05:13 PM