Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Harokey
Jun 12, 2003

Memory is RAM! Oh dear!
I have a constraint (due to gui stuff) that I want a dedicated "GUI" thread to make any gui calls.

I essentially need to be able to send functions over from the "main" thread to the "GUI" thread for the "GUI" thread to call. These functions will have an arbitrary number of arguments, and will often have a return value that I'll want to use in the "main" thread.

What I've done right now, is created a gui_call class, which has a virtual do_work() function. Any real gui_call I have inherits from this base class, and all the parameters are given to the class in the constructor. This is incredibly tedious, and there must be a better way. Often these gui_call's are just one function call (but sometimes they're more). Is boost::bind the correct way to do this instead of what I'm doing right now?

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



Hmm this is more of a design philosophy thing, but I think your approach sounds bad in some way.

The way I view software, the user interface drives the program, so the user interface is always the "main" program. Examples: The user launches a GUI that creates some backend objects the GUI will then drive to let the user do work. The user enters a command on a commandline, the CLI frontend parses the commandline, creates the appropriate backend objects, and drives them to perform the work the user requested. A remote client makes a request to the server interface, which drives the backend to serve the request.

What I want to say is, IMO you should not have the backend drive the UI, but the UI drive the backend. The backend should then have a notification interface where the UI can register to get updates on the work being performed. The result will be that the UI is aware of the backend and calls that directly, while the backend is only aware that someone has registered for change notifications.
For those change notifications, boost::bind sounds like a good choice. (Remember to wrap some appropriate synchronisation mechanism around this.)


On a side note, remember that it isn't uncommon for GUI libraries to require that all GUI code takes place in the main thread, i.e. the initial thread your main() function runs on. You're probably better off having a "main" thread that does GUI, and a "work" thread that does work. Of course this depends entirely on your platform, but if you're multi-platform you really want to have the main thread be the GUI thread.

Harokey
Jun 12, 2003

Memory is RAM! Oh dear!

nielsm posted:

:words:

As far as what the project I'm doing is. See this post: http://forums.somethingawful.com/showthread.php?threadid=2773485&pagenumber=207&perpage=40#post386889568 and the following posts.

This is a library used to teach CS1 courses using robots. Many programs written will have no graphical windows at all, only a terminal window. The graphical windows only exist when the students (users) request them. Furthermore, this is a port of a python library, so I need to emulate the way the Python Library does its stuff.

raminasi
Jan 25, 2005

a last drink with no ice
Is there an idiomatic workaround for the fact that you can't use remove_if on STL maps because you can't reorder them? (Or, if you can, how do you do it?)

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Harokey posted:

I have a constraint (due to gui stuff) that I want a dedicated "GUI" thread to make any gui calls.

I essentially need to be able to send functions over from the "main" thread to the "GUI" thread for the "GUI" thread to call. These functions will have an arbitrary number of arguments, and will often have a return value that I'll want to use in the "main" thread.

What I've done right now, is created a gui_call class, which has a virtual do_work() function. Any real gui_call I have inherits from this base class, and all the parameters are given to the class in the constructor. This is incredibly tedious, and there must be a better way. Often these gui_call's are just one function call (but sometimes they're more). Is boost::bind the correct way to do this instead of what I'm doing right now?

I've asked myself this question before, since I always end up with a similar solution to you for cross thread communication stuff. I was just googling around about bind, when I came across this:

http://www.codeproject.com/KB/library/BoostBindFunction.aspx

From what I can tell, he seems to have created a sort of generic Command class and he uses bind to attach function calls to it with arbitrary numbers of parameters. He then builds a vector of these commands, all attached to different functions, which he then iterates through, executing each function in sequence. I haven't tested it out myself, but it certainly looks like it might help solve the problem.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

GrumpyDoctor posted:

Is there an idiomatic workaround for the fact that you can't use remove_if on STL maps because you can't reorder them? (Or, if you can, how do you do it?)
There's no standard function, but it's not very hard to write one:
code:
template<class Container, class UnaryPredicate>
void erase_if(Container& cont, typename Container::iterator begin, typename Container::iterator end, UnaryPredicate pred) {
    while (begin != end) {
        if (pred(*begin)) {
            cont.erase(begin++);
        }
        else {
            ++begin;
        }
    }
}
Note that this works only for containers where erase does not invalidate other iterators.

brc64
Mar 21, 2008

I wear my sunglasses at night.
Okay, here's the deal. I'm in an introductory programming class (C++) that's mostly just a refresher from some intro classes I've taken years ago. However, now we're starting to work with strings, and that's somewhat new territory for me. And the instructor is terrible.

I'm not asking for you to do my homework for me, but I could use a bit of help to come up with the right algorithm for this assignment. I feel like I'm close, but I must be missing something simple. The assignment is to take a line of input ending with a '.' and format it so it looks like a proper sentence. Capitalize the first letter, remove extra spaces between words, and make the other letters lowercase. I've got the case stuff down... that's easy, but I'm stuck on the space problem.

My first approach was to just loop through the string and check the current index with the index next to it, and if they're both spaces, erase one of them:

code:
// starting at 1 because the first character is assumed to be a letter

for(int i=1; i<sentence.length(); i++){
     if((sentence[i]==' ') && (sentence[i+1]==' '))
          sentence.erase(i,1);
     }
Unfortunately, this method doesn't seem to work when there are more than two spaces. For example, the input "Testing one." end up comparing "g " and " o" in addition to " ", and an extra space is left in. At least, that seems to be the case, when I through some cout statements into the loop to try to help me debug.

I don't know if I'm just overthinking this or what, but I'm fairly stumped on which direction to go at this point. I've also thought about just removing all the spaces altogether and trying to mark the index of where they were so I could insert one after the fact, but I can't figure out how do accomplish that, either.

Any suggestions? Again, not looking for an outright answer, just a point in the right direction.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

brc64 posted:

Unfortunately, this method doesn't seem to work when there are more than two spaces. For example, the input "Testing one." end up comparing "g " and " o" in addition to " ", and an extra space is left in. At least, that seems to be the case, when I through some cout statements into the loop to try to help me debug.
It's supposed to be testing "g " and " o", that's not your problem. The problem you have is that when you erase a space you still move your index up one, when you need to check the same position again.

You also go one too far at the end of the loop, because you're looking at string[i+1] when i is the final character - not a big deal in this case since it'll just be a terminating null character, but a thing to be wary of in general.

brc64
Mar 21, 2008

I wear my sunglasses at night.

roomforthetuna posted:

It's supposed to be testing "g " and " o", that's not your problem. The problem you have is that when you erase a space you still move your index up one, when you need to check the same position again.

You also go one too far at the end of the loop, because you're looking at string[i+1] when i is the final character - not a big deal in this case since it'll just be a terminating null character, but a thing to be wary of in general.
I was wondering if that might be the case. And yes, I thought about the i+1. My initial code actually had i-1, which seemed like a reasonable idea since I was starting at index 1 instead of 0 anyway, but I was worried that it might have been contributing to the issues I was seeing.

So I need to repeat my check any time I erase a character, before advancing the index. Oh! I think I know how to do that! Time to test!

Thanks for the quick input!

Jethro
Jun 1, 2000

I was raised on the dairy, Bitch!
Or you need to change your loop to only increment the index when you don't erase a character.

brc64
Mar 21, 2008

I wear my sunglasses at night.

Jethro posted:

Or you need to change your loop to only increment the index when you don't erase a character.

Yeah, I think I've got it, but I can't get Visual C++ 2010 Express to compile even the same code that worked in Visual Studio 2008 in the school labs, so I guess I'm going to have to wait until I can get back to campus to test it out. Cheap community college doesn't even offer academic priced Microsoft software, or I'd probably just buy it. :(

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Also, just to catch this early in your learning, apparently it's better to get into the habit of "++i" rather than "i++" for various reasons. I habitually do i++ because I've already been doing it that way for years, but since you haven't, try to form the better habit!

brc64
Mar 21, 2008

I wear my sunglasses at night.

roomforthetuna posted:

Also, just to catch this early in your learning, apparently it's better to get into the habit of "++i" rather than "i++" for various reasons. I habitually do i++ because I've already been doing it that way for years, but since you haven't, try to form the better habit!
I really have no desire to pursue programming as a career, but I appreciate the input. My textbook talked about the difference between the two, but I barely understood it beyond "when the math happens". For my purposes, I think it's safe to assume they are equivalent.

Despite not wanting to write code for a living, I do love the knowledge I get from these classes, and it's amazing just how much even entry level programming helps with being able to troubleshoot problems with other software. What I would love would be a class devoted entirely to advanced shell scripting... that's more up my alley. Introductory programming gives me a nice stepping stone into learning more of that on my own, at least.

nielsm
Jun 1, 2009



brc64 posted:

I'm not asking for you to do my homework for me, but I could use a bit of help to come up with the right algorithm for this assignment. I feel like I'm close, but I must be missing something simple. The assignment is to take a line of input ending with a '.' and format it so it looks like a proper sentence. Capitalize the first letter, remove extra spaces between words, and make the other letters lowercase. I've got the case stuff down... that's easy, but I'm stuck on the space problem.

Are you required to modify the string in-place?
It might be easier to copy the source to a destination, one character at a time, and keep a bit of state. E.g. whether you are at the beginning of a sentence, whether the last copied character was a space. So sometimes you modify the character you copy, and sometimes you skip over a character without copying.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

roomforthetuna posted:

Also, just to catch this early in your learning, apparently it's better to get into the habit of "++i" rather than "i++" for various reasons. I habitually do i++ because I've already been doing it that way for years, but since you haven't, try to form the better habit!

Why is that? I always notice people tend to favor pre-incrementing, but I never really understood the logic as to why. Like you, I always use i++ unless I explicitly need to. I vaguely remember a friend who studied assembly code saying something about it being more efficient on some processors, but I kind of assumed that with modern optimizing compilers, it was irrelevant.

Jethro posted:

Or you need to change your loop to only increment the index when you don't erase a character.

I think you could also fix the issue by running through the string backwards:

code:
for(int i=sentence.length()-2; i>0; i--)
{
   if((sentence[i]==' ') && (sentence[i+1]==' '))
      sentence.erase(i+1,1);
}

Gerblyn fucked around with this message at 21:09 on Mar 11, 2011

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It's irrelevant on any modern compiler if the operand is of primitive type. If it's of class type, then using post-increment causes an unnecessary copy of the object. If the class just wraps some primitive type, then again that's probably irrelevant; but in the (very rare) case of a heavyweight iterator with serious internal state, that can be a major expense. I think this point tends to be overblown, but I certainly sympathize with people who say it's just simpler to teach people to always favor pre-increment.

rjmccall fucked around with this message at 21:15 on Mar 11, 2011

MutantBlue
Jun 8, 2001

brc64 posted:

code:
// starting at 1 because the first character is assumed to be a letter

for(int i=1; i<sentence.length(); i++){
     if((sentence[i]==' ') && (sentence[i+1]==' '))
          sentence.erase(i,1);
     }

Just do it this way, easy as pie :)
code:
sentence.erase(std::unique(sentence.begin(), sentence.end(), [](char a, char b){ return a == ' ' && b == ' '; }), sentence.end());

shodanjr_gr
Nov 20, 2007
I'm using C++ and QT for a multithreaded application that I have developed.

The second thread uses a bunch of DLLs for the stuff that it does.

I've noticed that the second thread sometimes hijacks the working directory of the application to the location of the DLLs that it loads (so relative paths defined in my code and/or external configuration files no longer work).

Is there a way to get around this? It seems very very random when it happens. Almost feels like a race condition of some sort.

Top Bunk Wanker
Jan 31, 2005

Top Trump Anger
Say I have a class and two derived classes, like this.
code:
class CBase {
public:
int member1;
int member2;
};

class CDerived: public cBase {
public:
bool member3;
};

class CDerived2: public cBase {
public:
char member4;
};
Is it possible to create a single STL vector that holds objects of all three of those types?

nielsm
Jun 1, 2009



Ghost Town Perv posted:

Say I have a class and two derived classes

Is it possible to create a single STL vector that holds objects of all three of those types?

You can't create a vector that contains objects of any of those three types, but you can create a vector that contains pointers to objects of any of those types.

code:
CBase o1;
CDerived o2;
CDerived o3;

std::vector<CBase> v1;
v1.push_back(o1); v1.push_back(o2); v1.push_back(o3);
// v1 now contains three CBase objects, the specifics of the derived classes
// were lost on insertion: The vector creates a copy using the CBase copy
// constructor.

std::vector<CBase *> v2;
v2.push_back(&o1); v2.push_back(&o2); v2.push_back(&o3);
// v2 now contains three CBase pointers, pointing respectively to one object
// of the CBase class, one of the CDerived class and one of the CDerived2
// class.
// Of course in this case, those objects are auto-allocated so when they go
// out of scope the pointers in the vector will no longer be valid.
When you pull the objects back out, you'll get CBase pointers and if you want to use them as a specific subclass you'll have to cast. If you want to be able to know what specific subclass an object is you must make sure that CBase has at least one virtual method (at least the destructor should be virtual) you can use dynamic_cast<>() to attempt casting the objects up to a more specific class, the dynamic_cast will return null if the attempted cast wasn't possible.

But you should not be attempting to cast up that way, in general. You should instead define an appropriate virtual method interface in CBase and implement it in the derived classes, to get the functionality you want through polymorphism.

When doing this, you'll need to be careful about memory management. You'll most often be allocating the objects on the heap (with operator new) so you need to remember to delete them again, which implies you need to figure out which part of your code should be responsible for deleting the objects. You can also look into using smart pointers instead.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Ghost Town Perv: Not directly, no; all the STL containers are homogenous. You can make it a vector of pointers (or smart pointers) to CBase, or you can make it a vector of a union of all the options, or you can figure out some other way making it homogenous, or you can roll your own crazy heterogenous vector class.

schnarf
Jun 1, 2002
I WIN.

nielsm posted:

...
You can also look into using smart pointers instead.

Just do this; don't bother with manual memory management. Make a vector< shared_ptr<CBase> >.

icantfindaname
Jul 1, 2008


When I try to compile this code in visual c++ express 2010 on windows 7, it gives me a bunch of syntax errors on the brackets in the sort function:

code:
9    void sort (int *array1, int length)
10   {
11	     quick (array1, array1 + length - 1);
12   }
13
14   void quick (int *left, int *right)
15   {
16	     if (right > left) {
17		     int pivot = left [(right - left) / 2];
18		     int *r = right;
19		     int *l = left;
20
21		     while (1) {
22			     while (*l < pivot) l++;
23			     while (*r > pivot) r--;
24			     if (l <= r) {
25				     int t = *l;
26				     *l++ = *r;
27				     *r-- = t;
28			     }
29		     if (l > r) break;
30		     }
31
32		     quick (left, r);
33		     quick (l, right);
34	     }
35   }
The errors:
code:
1>quicksort.cpp(9): error C2143: syntax error : missing ')' before 'constant'
1>quicksort.cpp(9): error C2143: syntax error : missing ';' before 'constant'
1>quicksort.cpp(9): error C2059: syntax error : ')'
1>quicksort.cpp(10): error C2143: syntax error : missing ';' before '{'
1>quicksort.cpp(10): error C2447: '{' : missing function header (old-style formal list?)
There's probably a stupid reason but I can't see it, any help?

MutantBlue
Jun 8, 2001

icantfindaname posted:

When I try to compile this code in visual c++ express 2010 on windows 7, it gives me a bunch of syntax errors on the brackets in the sort function:

The errors:
code:
1>quicksort.cpp(9): error C2143: syntax error : missing ')' before 'constant'
1>quicksort.cpp(9): error C2143: syntax error : missing ';' before 'constant'
1>quicksort.cpp(9): error C2059: syntax error : ')'
1>quicksort.cpp(10): error C2143: syntax error : missing ';' before '{'
1>quicksort.cpp(10): error C2447: '{' : missing function header (old-style formal list?)

Those line numbers (9,10,11,...) aren't actually in your source file are they? I get similar errors if I don't edit out the line numbers.

icantfindaname
Jul 1, 2008


MutantBlue posted:

Those line numbers (9,10,11,...) aren't actually in your source file are they? I get similar errors if I don't edit out the line numbers.

I added them to show the lines in the error messages. On second thought, here's the whole program

code:
// quicksort.cpp : main project file.

#include "stdafx.h"
#include <stdio.h>
#include "simpio.h"

#define length 16

void sort (int *array1, int length)
{
	quick (array1, array1 + length - 1);
}

void quick (int *left, int *right)
{
	if (right > left) {
		int pivot = left [(right - left) / 2];
		int *r = right;
		int *l = left;

		while (1) {
			while (*l < pivot) l++;
			while (*r > pivot) r--;
			if (l <= r) {
				int t = *l;
				*l++ = *r;
				*r-- = t;
			}
		if (l > r) break;
		}

		quick (left, r);
		quick (l, right);
	}
}

int main (void)
{
	int i;

	int array1 [length];

	printf ("Enter %d elements seperately: ", length);

	for (i = 0; i < length; i++) {
		array1 [i] = GetInteger();
	}

	for (i = 0; i < length; i++) printf ("[%d]", array1[i]);
	printf ("\n");

	sort (array1, length);
	
	for (i = 0; i < length; i++) printf ("[%d]", array1[i]);
	printf ("\n");

	getchar ();
}
Sorry about that

pseudorandom name
May 6, 2007

pre:
$ clang -Wall qs.c 
qs.c:10:29: error: expected ')'
void sort (int *array1, int length)
                            ^
qs.c:6:16: note: instantiated from:
#define length 16
               ^
qs.c:10:11: note: to match this '('
void sort (int *array1, int length)
          ^
qs.c:10:29: error: parameter name omitted
void sort (int *array1, int length)
                            ^
qs.c:6:16: note: instantiated from:
#define length 16
               ^
edit: and here's gcc, just for laughs:
pre:
$ gcc -Wall qs.c 
qs.c:10:29: error: expected ‘;’, ‘,’ or ‘)’ before numeric constant
All hail the mighty clang!

MutantBlue
Jun 8, 2001

icantfindaname posted:

I added them to show the lines in the error messages. On second thought, here's the whole program

code:
#define length 16

void sort (int *array1, int length)

That #define tells the preprocessor to replace "length" with "16" everywhere it sees it. This makes the next line look like "void sort (int *array1, int 16)" and the "int 16" is where the error is.

That Turkey Story
Mar 30, 2003

icantfindaname posted:

I added them to show the lines in the error messages. On second thought, here's the whole program

code:
#define length 16

void sort (int *array1, int length)
{
	quick (array1, array1 + length - 1);
}

#define does a textual replacement. You #define'd "length" to mean 16. This means that line 9 is equivalent to void sort (int *array1, int 16) which doesn't make any sense.

nielsm
Jun 1, 2009



MutantBlue posted:

That #define tells the preprocessor to replace "length" with "16" everywhere it sees it. This makes the next line look like "void sort (int *array1, int 16)" and the "int 16" is where the error is.

Lesson to take: Always write macros with uppercase, like LENGTH. Or, since you're actually writing C++ (your file is named .cpp), make a proper constant:
code:
const int length = 16;

MutantBlue
Jun 8, 2001

nielsm posted:

Lesson to take: Always write macros with uppercase, like LENGTH. Or, since you're actually writing C++ (your file is named .cpp), make a proper constant:
code:
const int length = 16;

If you're actually writing C++ use std::sort()

nielsm
Jun 1, 2009



MutantBlue posted:

If you're actually writing C++ use std::sort()

It looks like it might be some kind of homework or other. The C standard library also has a qsort() function.

icantfindaname
Jul 1, 2008


nielsm posted:

It looks like it might be some kind of homework or other. The C standard library also has a qsort() function.

Yep, and thanks, it works now

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

nielsm posted:

Lesson to take: Always write macros with uppercase, like LENGTH. Or, since you're actually writing C++ (your file is named .cpp), make a proper constant:
code:
const int length = 16;
Though you should probably do that uppercase too anyway, since you've got "length" as a function parameter name too which leaves the risk of accidentally expecting to be using the global variable when you're actually using the local. Distinguishing globals from locals in some way is a good idea. I use all uppercase for const globals, same as if they were macros, all lowercase for locals, and UpperFirsts for globals and member variables. Microsoft's way of choice (at least in their DirectX example code) is g_thing for globals, m_thing for members.

Basically, do something so you don't reuse global variable names in local scope because it won't ever make things easier, and will sometimes make things annoying as gently caress.

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

I want to overload the << and >> operators on my class to make it easier to print and read to it. But I'm getting this error:

utils.h:33: error: no match for 'operator>>' in 's >> city->cityinfo_c::name'

here is the code:
code:
class cityinfo_c
{
    string name;
    int locale_ID;
    int type_ID;
    int population;
    double latitude;
    double longitude;
    friend istream& operator>>(istream&, const cityinfo_c &);
    friend ostream& operator<<(ostream&, const cityinfo_c &);
};

istream& operator>>(istream&s, const cityinfo_c &city) //overload for easy input with >>
{
    return s
        >> city.name
        >> city.locale_ID
        >> city.type_ID
        >> city.latitude
        >> city.longitude
        >> city.population;
}

ostream& operator<<(ostream&s, const cityinfo_c &city) //overload for easy formatted output
{
    return s
        << setw(20) << city.name
        << setw(12) << LOCALE[city.locale_ID]
        << setw(10) << TYPE[city.type_ID]
        << setw(6) << right << city.population
        << setw(6) << right << city.latitude
        << setw(6) << right << city.longitude
        << endl;
}

Nippashish
Nov 2, 2005

Let me see you dance!

A MIRACLE posted:

code:
istream& operator>>(istream&s, const cityinfo_c &city) 

You're about to stuff a bunch of stuff into that cityinfo_c, it doesn't make sense for it to be const.

Clobbersaurus
Feb 26, 2004

How do you guys handle memory profiling?

I've been trying to use ps -u and valgrind and I've been sort of confused by the output - I know it's sort of naïve to say I want to know 'only' the heap and stack usage - but what values are most accurate for measuring this? What do you look at?

I'm writing a program that needs to be really memory efficient for a large number of entries that each get malloced. I had been using the resident set size field of ps -u, but I think the heap isn't represented by it.

HFX
Nov 29, 2004

Clobbersaurus posted:

How do you guys handle memory profiling?

I've been trying to use ps -u and valgrind and I've been sort of confused by the output - I know it's sort of naïve to say I want to know 'only' the heap and stack usage - but what values are most accurate for measuring this? What do you look at?

I'm writing a program that needs to be really memory efficient for a large number of entries that each get malloced. I had been using the resident set size field of ps -u, but I think the heap isn't represented by it.

I use the massif for valgrind. As long as you are using a semi recent version, it should show heap and memory usage and break down where they occured and how much is being used by them. Massif's whole job is memory profiling.

Clobbersaurus
Feb 26, 2004

HFX posted:

I use the massif for valgrind. As long as you are using a semi recent version, it should show heap and memory usage and break down where they occured and how much is being used by them. Massif's whole job is memory profiling.

Cool! So if I'm interpreting this correctly - the total heap usage is then the mem_heap_B + mem_head_extra_B?, where the 'extra' is just the overhead on malloc references and heap structure and all that?

HFX
Nov 29, 2004

Clobbersaurus posted:

Cool! So if I'm interpreting this correctly - the total heap usage is then the mem_heap_B + mem_head_extra_B?, where the 'extra' is just the overhead on malloc references and heap structure and all that?

You got it. Extra might also include some bytes not yet allocated to you, but are in the same page.

Adbot
ADBOT LOVES YOU

Elfforkusu
Jan 15, 2011

HFX posted:

I use the massif for valgrind. As long as you are using a semi recent version, it should show heap and memory usage and break down where they occured and how much is being used by them. Massif's whole job is memory profiling.

Seconding this, with the addition that Massif Visualizer is freaking fantastic for viewing the output.

That said, learning a bit about malloc works on your platform (16 byte chunks, linux's fastbin thingy) is probably just as helpful.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply