![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Orchid XP v8 <voi### [at] dev null> wrote:
> OK, any C++ experts have any idea why this code snippet causes my
> program to crash at runtime?
> typedef std::vector<bool> Codeword;
> std::string codeword(const Codeword &c)
> {
> std::string out;
> for (unsigned int i=0; i<c.size(); i++)
> if (c[i]) out.append("1"); else out.append("0");
> return out;
> }
I can't see anything wrong with it, and I tried it and there was
nothing wrong with it. The error must be somewhere else.
If you are running it in linux, try running it using valgrind (if you
don't have it, install it; it's essential). In other words:
valgrind ./yourprogram
If will tell you if you have some out-of-bounds access or memory leaks.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> I can't see anything wrong with it, and I tried it and there was
> nothing wrong with it. The error must be somewhere else.
Right. So maybe I'm passing it a reference to something that doesn't
exist anymore then?
> If you are running it in linux, try running it using valgrind (if you
> don't have it, install it; it's essential). In other words:
>
> valgrind ./yourprogram
>
> If will tell you if you have some out-of-bounds access or memory leaks.
M$ Visual Studio is telling me something is wrong, but it isn't telling
me much beyond that. (I probably need to figure out how to work the
debugger first...)
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Orchid XP v8 <voi### [at] dev null> wrote:
> Warp wrote:
> > I can't see anything wrong with it, and I tried it and there was
> > nothing wrong with it. The error must be somewhere else.
> Right. So maybe I'm passing it a reference to something that doesn't
> exist anymore then?
Without seeing the whole program it's impossible to tell.
Btw, have you been using the at() function rather than operator [] like
I have been suggesting?
> > If you are running it in linux, try running it using valgrind (if you
> > don't have it, install it; it's essential). In other words:
> >
> > valgrind ./yourprogram
> >
> > If will tell you if you have some out-of-bounds access or memory leaks.
> M$ Visual Studio is telling me something is wrong, but it isn't telling
> me much beyond that. (I probably need to figure out how to work the
> debugger first...)
Just compile in debug mode and run the debugger (F5).
However, the Visual Studio debugger won't tell you if you have, for
example, a memory leak. The place where the program crashes (which will
be shown by the debugger) is not necessarily the place where the bug is.
It might be able to tell you if you are writing out of bounds or accessing
freed memory, but not necessarily. Valgrind will be able to do that.
Unfortunately, AFAIK, valgrind is not available for Windows or VS projects,
so you'll have to do the testing in linux.
(Profilers like valgrind which support VS programs in Windows exist,
but I know of no free one.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> Just compile in debug mode and run the debugger (F5).
>
> However, the Visual Studio debugger won't tell you if you have, for
> example, a memory leak. The place where the program crashes (which will
> be shown by the debugger) is not necessarily the place where the bug is.
True; sometimes you have to step carefully through the program to see what
it's doing and figure out where your memory management is going wrong. In
this case though, the error is
"Unhandled exception at 0x00414166 in Huffman01.exe: 0xC0000005: Access
violation reading location 0x00000004."
Access violation reading location 0x00000004 means it's very likely you're
dereferencing a NULL pointer somewhere, because of how close 4 is to 0. (The
program is taking a NULL pointer, treating it as a struct or class of some
sort, and trying to get the member that is 4 bytes into it.) So, if you just
hit F5 and run the program as usual, it will tell you right where it is when
it crashes by pointing at the line. You can also look at the call stack pane
to see how it got there. It will probably be easy to see what the NULL
pointer is.
- Slime
[ http://www.slimeland.com/ ]
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> for (unsigned int i=0; i<c.size(); i++)
> if (c[i]) out.append("1"); else out.append("0");
This isn't the cause of your crash, but I recommend not squishing your code
together like that. Keep each statement on a separate line and use brackets
around anything that's not a single simple statement:
for ( unsigned int i = 0; i < c.size(); i++ )
{
if ( c[i] )
out.append( "1" );
else
out.append( "0" );
}
Also put spaces around your operators like "=", "+" and "<". Readable code
is superior to short code.
- Slime
[ http://www.slimeland.com/ ]
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Slime wrote:
>> for (unsigned int i=0; i<c.size(); i++)
>> if (c[i]) out.append("1"); else out.append("0");
>
> This isn't the cause of your crash, but I recommend not squishing your code
> together like that. Keep each statement on a separate line and use brackets
> around anything that's not a single simple statement:
>
> for ( unsigned int i = 0; i < c.size(); i++ )
> {
> if ( c[i] )
> out.append( "1" );
> else
> out.append( "0" );
> }
If he wants brevity he could also code it like this:
for (int i = 0; i < c.size(); i++)
out.append(c[i] ? "1" : "0");
which is just as valid and avoids running the if/else together.
-- Chris
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Slime wrote:
> "Unhandled exception at 0x00414166 in Huffman01.exe: 0xC0000005: Access
> violation reading location 0x00000004."
>
> Access violation reading location 0x00000004 means it's very likely you're
> dereferencing a NULL pointer somewhere, because of how close 4 is to 0.
Yeah, seems plausible. (Except that I'm not using pointers anywhere,
only references.)
> So, if you just
> hit F5 and run the program as usual, it will tell you right where it is when
> it crashes by pointing at the line. You can also look at the call stack pane
> to see how it got there. It will probably be easy to see what the NULL
> pointer is.
It's somewhere inside vector.cpp. (And the code makes *no sense* to me
at all. The comments mumble something about copy constructors though...)
Now if I could somehow figure out which part of *my* code is calling the
failing routine, and with what arguments, I'd have a shot...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Without seeing the whole program it's impossible to tell.
Well, the program isn't that large, so just for a giggle I'll include it
here. The compiler claims there's nothing wrong with it, but clearly
there is. I can't wait to see how many different kinds of mistake I've
made... :-}
#include <iostream>
#include <vector>
#include <string>
typedef char Symbol;
typedef std::vector<bool> Codeword;
std::string codeword(const Codeword &c)
{
std::string out;
for (unsigned int i=0; i<c.size(); i++)
if (c[i]) out.append("1"); else out.append("0");
return out;
}
class SymbolInfo
{
public:
Symbol symbol;
double prob;
Codeword code;
SymbolInfo(Symbol s, double pr) : code()
{
symbol = s;
prob = pr;
}
void prefix(const bool p)
{
code.push_back(p);
}
};
class Tree
{
public:
Tree(SymbolInfo& s) : symbols()
{
symbols.push_back(s);
prob = s.prob;
}
void join(const Tree& tree)
{
for (unsigned int i=0; i<symbols.size(); i++)
symbols[i].prefix(false);
for (unsigned int i=0; i<tree.symbols.size(); i++)
{
SymbolInfo s = tree.symbols[i];
s.prefix(true);
symbols.push_back(s);
prob += s.prob;
}
}
const Codeword& lookup(const Symbol key)
{
for (unsigned int i=0; i<symbols.size(); i++)
if (symbols[i].symbol == key) return symbols[i].code;
}
const double Prob() {return prob;}
private:
std::vector<SymbolInfo> symbols;
double prob;
};
const Tree& build_tree(std::vector<SymbolInfo> info)
{
std::vector<Tree> trees;
for (unsigned int i=0; i<info.size(); i++)
{
Tree t(info[i]);
trees.push_back(t);
}
while (trees.size() > 1)
{
int index = 0;
for (unsigned int i = 1; i<trees.size(); i++)
if (trees[i].Prob() < trees[index].Prob()) index = i;
Tree t0 = trees[index];
trees.erase(trees.begin() + index);
index = 0;
for (unsigned int i = 1; i<trees.size(); i++)
if (trees[i].Prob() < trees[index].Prob()) index = i;
Tree t1 = trees[index];
trees.erase(trees.begin() + index);
t0.join(t1);
trees.push_back(t0);
}
return trees[0];
}
int main()
{
SymbolInfo A('A', 0.5);
SymbolInfo B('B', 0.25);
SymbolInfo C('C', 0.125);
SymbolInfo D('D', 0.125);
std::vector<SymbolInfo> symbols;
symbols.push_back(A);
symbols.push_back(B);
symbols.push_back(C);
symbols.push_back(D);
Tree t = build_tree(symbols);
std::cout << "A: " << codeword(t.lookup('A')) << std::endl;
std::cout << "B: " << codeword(t.lookup('B')) << std::endl;
std::cout << "C: " << codeword(t.lookup('C')) << std::endl;
std::cout << "D: " << codeword(t.lookup('D')) << std::endl;
}
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> It's somewhere inside vector.cpp. (And the code makes *no sense* to me at
> all. The comments mumble something about copy constructors though...)
Yeah, the STL code provided with visual studio is very unreadable.
> Now if I could somehow figure out which part of *my* code is calling the
> failing routine, and with what arguments, I'd have a shot...
You need to find the call stack window. It will give you a list of the
functions that called each other to get where the code is currently
executing. It should be one of the tabs along the bottom when debugging, or
you might have to look through the menus (under "window" or "debug") to turn
it on. Then you can double click on each level of function call and see what
its local variables' values are.
- Slime
[ http://www.slimeland.com/ ]
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> const Tree& build_tree(std::vector<SymbolInfo> info)
> {
> std::vector<Tree> trees;
>
...
>
> return trees[0];
> }
You are returning a reference to a local variable. When the function
finishes, trees' destructor will be called and all of its contents will be
deallocated. So you're returning a reference to invalid memory. If you're
not worried about copying Trees around, you can just remove the & from the
return type.
You might also want to assert( trees.size() > 0 ) to make sure the function
worked properly and there's something there to return.
That's the only actual problem I see. Otherwise I'm a little worried,
efficiency-wise, about how many vectors you're copying around, but that may
not be worth worrying about at this stage.
- Slime
[ http://www.slimeland.com/ ]
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |