So I got a structure, that holds an integer. I usually create that structure on the heap. If I now pass a pointer to such a structure into a function and use the integer member, would it be faster if I at first copied the members value on the stack and use that local variable in the function, or should I access the member through the pointer? What is potentially faster? Obviously I dont want to modify the member value. Code example:
Sample structure:
struct sample_s
{
int sample_member;
}
Way 1:
void sample_func(struct sample_s *sample_instance)
{
for(int i = 0; i < 1000; i++)
{
printf("%d", sample_instance->sample_member);
}
}
Way 2:
void sample_func_two(struct sample_s *sample_instance)
{
int a = sample_instance->sample_member;
for(int i = 0; i < 1000; i++)
{
printf("%d", a);
}
}
In your specific case, sample_func_two is potentially faster. This is because you're calling an external function, printf:
printf("%d", sample_instance->sample_member);
The compiler probably doesn't know that this call won't modify *sample_instance1, so it will reload sample_member from memory each time through the loop.
Now as for whether that makes an actual difference in the running time of your program, you'll have to benchmark it yourself.
1 The compiler doesn't know because it can't see the code of printf (it's in a library somewhere) and printf is not declared pure. In fact, printf can't be declared pure because depending on the format string it may write through its arguments (with %n).
Related
void input(int B[XAM][XAM])
{ int i,j,a;
for (i=0;i<3;i++) {
for (j=0; j<3; j++) {
scanf("%d",&B[i][j]);
}
}
for (i=0;i<3;i++) {
for (j=0; j<3; j++) {
printf("%d ",B[i][j]);
}
printf("\n");
}
}
void main()
{
#define XAM 3
int pilih,A[10],B[3][3],i,j;
input(&B[XAM][XAM]);
for (i=0;i<3;i++) {
for (j=0; j<3; j++) {
printf("%d ",B[i][j]);
}
printf("\n");
}
getch();
}
why when i try to run the program, I already used "Pass by reference", but still when I call the output from void main, the output didn't the same as my input from the procedure,
but if I call the output from the procedure, there is no problem
can someone help me why pass the reference didn't work?
thanks
you are passing the address (&) of [3][3] element of B using:
&B[3][3]
Just write
input(B);
Note that passing by reference is not done when you are calling funtcion, but when you are defining, so:
int foo(Foo& f);
passes f as reference when using it simply like foo(f);
But
int foo(Foo f);
in case where Foo is not a pointer (your B is a pointer) would end in compilation error, when trying foo(&f).
Also it would be good if you used XAM constant in B definition
B[3][3] -> B[XAM][XAM]
And turn on warnings in your compilator!
You want to pass the array by reference.
Whether or not a function parameter is passed by reference or by value is decided at the function's signature. You have to change the parameter type such that it's a reference to an array. That's done by adding the ampersand & to the parameter name.
For arrays, parentheses need to be added which needs getting used to:
void input(int (&B)[XAM][XAM]) {
// ...
}
When calling that function, simply pass B without mentioning the dimensions or using the & operator (that does something different when used at values!). That means, calling the function is written as if the argument was passed by value (no syntactical difference there), but of course it is passed by reference since the function's signature says so.
input(B);
Indeed, passing arrays by reference is the only way to pass an array as an array. Otherwise (if your parameter looks like int B[XAM][XAM]), only a pointer to the first element is actually passed, and it isn't treated as an array within the function. You can easily check how it is treated in the function body by using the sizeof operator.
Related question: Passing an array by reference
[edit] Outside of this get method (see below), i'd like to have a pointer double * result; and then call the get method, i.e.
// Pull results out
int story = 3;
double * data;
int len;
m_Scene->GetSectionStoryGrid_m(story, data, len);
with that said, I want to a get method that simply sets the result (*&data) by reference, and does not dynamically allocate memory.
The results I am looking for already exist in memory, but they are within C-structs and are not in one continuous block of memory. Fyi, &len is just the length of the array. I want one big array that holds all of the results.
Since the actual results that I am looking for are stored within the native C-struct pointer story_ptr->int_hv[i].ab.center.x;. How would I avoid dynamically allocating memory like I am doing above? I’d like to point the data* to the results, but I just don’t know how to do it. It’s probably something simple I am overlooking… The code is below.
Is this even possible? From what I've read, it is not, but as my username implies, I'm not a software developer. Thanks to all who have replied so far by the way!
Here is a snippet of code:
void GetSectionStoryGrid_m( int story_number, double *&data, int &len )
{
std::stringstream LogMessage;
if (!ValidateStoryNumber(story_number))
{
data = NULL;
len = -1;
}
else
{
// Check to see if we already retrieved this result
if ( m_dStoryNum_To_GridMap_m.find(story_number) == m_dStoryNum_To_GridMap_m.end() )
{
data = new double[GetSectionNumInternalHazardVolumes()*3];
len = GetSectionNumInternalHazardVolumes()*3;
Story * story_ptr = m_StoriesInSection.at(story_number-1);
int counter = 0; // counts the current int hv number we are on
for ( int i = 0; i < GetSectionNumInternalHazardVolumes() && story_ptr->int_hv != NULL; i++ )
{
data[0 + counter] = story_ptr->int_hv[i].ab.center.x;
data[1 + counter] = story_ptr->int_hv[i].ab.center.y;
data[2 + counter] = story_ptr->int_hv[i].ab.center.z;
m_dStoryNum_To_GridMap_m.insert( std::pair<int, double*>(story_number,data));
counter += 3;
}
}
else
{
data = m_dStoryNum_To_GridMap_m.find(story_number)->second;
len = GetSectionNumInternalHazardVolumes()*3;
}
}
}
Consider returning a custom accessor class instead of the "double *&data". Depending on your needs that class would look something like this:
class StoryGrid {
public:
StoryGrid(int story_index):m_storyIndex(story_index) {
m_storyPtr = m_StoriesInSection.at(story_index-1);
}
inline int length() { return GetSectionNumInternalHazardVolumes()*3; }
double &operator[](int index) {
int i = index / 3;
int axis = index % 3;
switch(axis){
case 0: return m_storyPtr->int_hv[i].ab.center.x;
case 1: return m_storyPtr->int_hv[i].ab.center.y;
case 2: return m_storyPtr->int_hv[i].ab.center.z;
}
}
};
Sorry for any syntax problems, but you get the idea. Return a reference to this and record this in your map. If done correctly the map with then manage all of the dynamic allocation required.
So you want the allocated array to go "down" in the call stack. You can only achieve this allocating it in the heap, using dynamic allocation. Or creating a static variable, since static variables' lifecycle are not controlled by the call stack.
void GetSectionStoryGrid_m( int story_number, double *&data, int &len )
{
static g_data[DATA_SIZE];
data = g_data;
// continues ...
If you want to "avoid any allocation", the solution by #Speed8ump is your first choice! But then you will not have your double * result; anymore. You will be turning your "offline" solution (calculates the whole array first, then use the array elsewhere) to an "online" solution (calculates values as they are needed). This is a good refactoring to avoid memory allocation.
This answer to this question relies on the lifetime of the doubles you want pointers to. Consider:
// "pointless" because it takes no input and throws away all its work
void pointless_function()
{
double foo = 3.14159;
int j = 0;
for (int i = 0; i < 10; ++i) {
j += i;
}
}
foo exists and has a value inside pointless_function, but ceases to exist as soon as the function exits. Even if you could get a pointer to it, that pointer would be useless outside of pointless_function. It would be a dangling pointer, and dereferencing it would trigger undefined behavior.
On the other hand, you are correct that if you have data in memory (and you can guarantee it will live long enough for whatever you want to do with it), it can be a great idea to get pointers to that data instead of paying the cost to copy it. However, the main way for data to outlive the function that creates it is to call new, new[], or malloc. You really can't get out of that.
Looking at the code you posted, I don't see how you can avoid new[]-ing up the doubles when you create story. But you can then get pointers to those doubles later without needing to call new or new[] again.
I should mention that pointers to data can be used to modify the original data. Often that can lead to hard-to-track-down bugs. So there are times that it's better to pay the price of copying the data (which you're then free to muck with however you want), or to get a pointer-to-const (in this case const double* or double const*, they are equivalent; a pointer-to-const will give you a compiler error if you try to change the data being pointed to). In fact, that's so often the case that the advice should be inverted: "there are a few times when you don't want to copy or get a pointer-to-const; in those cases you must be very careful."
//Prints out a given array
template <typename T>
void print(T t)
{
for(int i = 0; i < t.size(); i++)
{
cout << t[i] << " ";
}
cout << endl;
}
I have an idea but it includes passing the size of the array. Is it possible to avoid this?
*Update
Thanks for all of the answers/ideas but this problem is getting way deeper than my snorkeler can handle. I wanted to rewrite my C++ code in C because it was horribly written and slow. I see now that I have an opportunity to make it even worse in C. I'll rewrite it from the ground up in Python(performance be damned). Thanks again
If you don't have ELEMENTS, it's
#define ELEMENTS(a) (sizeof(a)/sizeof(*a))
Then,
#define print_array(a, specifier) print_array_impl(a, specifier, ELEMENTS(a), sizeof(*a))
void print_array_impl(void* a, char* specifier, size_t asize, size_t elsize)
{
for(int i = 0; i < asize; i++)
{
// corrected based on comment -- unfortunately, not as general
if (strcmp(specifier, "%d") == 0)
printf(specifier, ((int*)a)[i]);
// else if ... // check other specifiers
printf(" ");
}
printf("\n");
}
Use like this
print_array(a, "%d") // if a is a int[]
and, a needs to be an array name, not a pointer (or else ELEMENTS won't work)
You cannot know what is the size of an array without passing the size of that array (except operating with sizeof in static arrays). This is because the a pointer to a block of memory will only point to the base of the block of memory, from which you can know where the array/block of memory starts, but as there is no end defined you cannot determine where it will end.
You either need to set your own length per array and preserve it, and use it with the array like as described:
You can make a new type like:
struct _my_array {
typename arr[MAX];
int n;
} my_array;
OR
struct _my_array {
typename *arr;
int n;
} my_array;
In this case you need to allocate the a block of memory dynamically with new or malloc , and when finished free the memory with delete or free (respectively).
Or you can simply pass the array number of elements through the function.
Another way is to use a special terminator value of your array type which if encountered will be determined as the end of the array. In this case you need not preserve the size. For example a string is '\0' terminated, so all the string functions know that when a '\0' character is encounter in the char array it will consider that the string has end.
UPDATE
Because this is a generic function and the array can be of any type, one thing which you can do is like this:
struct _my_generic_arr {
void *arr;
int n;
int type;
} my_generic_arr;
When populating this array you can use any type. To identify which type, pass an identified in the type component. Each unique value will determine which type does the arr pointer actually points to (was actually the intended type to be pointed). The n will define the length. Now, depending on different values of type make a switch - case or an if - else ladder or nest, and process the array as you need.
It is impossible in c to track the size of an array in other block,,
It would be a better option to pass the size of the array along..
The other option would be to declare a global variable that has the size and using that variable inside the function
Eg,,
int size=<some value>
void main()
{
int arr[<same value>];
}
void print(T t)
{
for(int i = 0; i < size; i++)
{
printf("%d ",t[i]) //assuming T as int
}
printf("\n");
}
In C, you would need to pass two additional parameters: the size of the array (as you mentioned), and some way of indicating how to convert t[i] into a string. To convert t[i] to a string, you could create a custom switch statement to decode possible types, pass a pointer to a function that will return the string pointer, or you could pass the printf format specifier (e.g. "%d" for integer).
The problem is larger than you think. If you have an array of size 12, how do you know what data is held in that array? It could be 3 char*'s (on 32 bit system), 3 int32_t's, or even 12 chars. You have no way of knowing how to interpret the data. The best you could do is to implement your own version of a v-table and putting a print or toString function into it.
typedef struct {
void *array;
size_t length;
int element_width;
printer_t to_string;
} container;
printer_t is a type that describes a function pointer that takes an element pointer and returns a string (or prints it, if you don't want to free the string). This is almost never worth doing in C. That doesn't mean it can't be done. I would emphasize, though, that none of this is intended to imply that it should be done.
The function itself would look something like this:
void print(container *thing)
{
size_t offset;
int width;
char *stringified;
width = thing->element_width;
for (offset = 0; offset * width < thing->length; offset += width)
{
stringified = thing->to_string(thing->array + offset);
printf("%s ", stringified);
free(stringified);
}
}
What this does is essentially turn a struct into a faux class with a function pointer for a method. You could be more object-oriented and put the method in the type being printed and make it an array of those instead. Either way, it's not a good idea. C is for writing C. If you try to write in a different language, you'll end up with all sorts of terrible stuff like this.
Sample Function 1
int func1 (int arg)
{
return arg + 10;
}
Sample Function 2
int func1 (int arg)
{
int retval = arg + 10;
return retval;
}
func_xyz (int x);
int main ()
{
int a = 10;
int p = func1 (a);
func_xyz(p);
}
Is there any difference between runtime behaviour of these functions (sample 1 and sample 2)?
I have a function definition in my code that uses sample 1 style function definition. When i invoke this function, a million times (not reproducable for lesser iterations) and try to pass this value to func_xyz, i get a segfault. However, when i use sample 2 style definition, segfault goes away. But i am unable to understand the reason for this behavior.
in THEORY in function2 a local variable will be initiated (which will take just a bit more space), then the calculation will be calculated and value will be copied to the variable's location.
After that the copy will be copied to the return value. So that's an extra copy operation.
in REALITY compilers do that optimization in compile time, and remove unneeded variables if their value isn't actually used. (refactoring)
Here are some details about the return value optimization in compilers.
Try with a class that has a non-trivial copy constructor to see what is actually happening.
There is absolutely no difference. Any compiler can see that the code is just
int main()
{
func_xyz(20);
}
What does the called function do??
Alright, I'm guessing this is an easy question, so I'll take the knocks, but I'm not finding what I need on google or SO. I'd like to create an array in one place, and populate it inside a different function.
I define a function:
void someFunction(double results[])
{
for (int i = 0; i<100; ++i)
{
for (int n = 0; n<16; ++n) //note this iteration limit
{
results[n] += i * n;
}
}
}
That's an approximation to what my code is doing, but regardless, shouldn't be running into any overflow or out of bounds issues or anything. I generate an array:
double result[16];
for(int i = 0; i<16; i++)
{
result[i] = -1;
}
then I want to pass it to someFunction
someFunction(result);
When I set breakpoints and step through the code, upon entering someFunction, results is set to the same address as result, and the value there is -1.000000 as expected. However, when I start iterating through the loop, results[n] doesn't seem to resolve to *(results+n) or *(results+n*sizeof(double)), it just seems to resolve to *(results). What I end up with is that instead of populating my result array, I just get one value. What am I doing wrong?
EDIT
Oh fun, I have a typo: it wasn't void someFunction(double results[]). It was:
void someFunction(double result[])...
So perhaps this is turning into a scoping question. If my double result[16] array is defined in a main.cpp, and someFunction is defined in a Utils.h file that's included by the main.cpp, does the result variable in someFunction then wreak havoc on the result array in main?
EDIT 2:
#gf, in the process of trying to reproduce this problem with a fresh project, the original project "magically" started working.
I don't know how to explain it, as nothing changed, but I'm pretty sure of what I saw - my original description of the issue was pretty clear, so I don't think I was hallucinating. I appreciate the time and answers...sorry for wasting your time. I'll update again if it happens again, but for the meantime, I think I'm in the clear. Thanks again.
Just a point about the variable scope part of the question - there is no issue of variable scope here. result/results in your someFunction definition is a parameter -> it will take on the value passed in. There is no relation between variables in a called function and it's caller -> the variables in the caller function are unknown to the called function unless passed in. Also, variable scoping issues do not occur between routines in C++ because there are no nested routines. The following pieces of code would demonstrate scoping issues:
int i = 0;
{
int i = 0;
i = 5; //changes the second i, not the first.
//The first is aliased by the second i defined first.
}
i = 5; //now changes the first i; the inner block is gone and so is its local i
so if C++ did have nested routines, this would cause variable scoping
void main()
{
double results[16];
double blah[16];
doSomething(blah);
void doSomething(double * results)
{
//blah doing something here uses our parameter results,
//which refers to blah, but not to the results in the higher scope.
//The results in the higher scope is hidden.
}
}
void someFunction(double results[])
should be exactly equivalent to
void someFunction(double *results)
Try using the alternative declaration and see if the problem persists.
To me it seems that your code should simply work.
I just tried this in g++ and worked fine. I guess your problem is elsewhere? have you tried the snipped you posted?
#include <iostream>
void someFunction(double results[])
{
for (int i = 0; i<100; ++i)
{
for (int n = 0; n<16; ++n) //note this iteration limit
{
results[n] += i * n;
}
}
}
int main()
{
double result[16];
for(int i = 0; i<16; i++)
{
result[i] = -1;
}
someFunction(result);
for(int i = 0; i<16; i++)
std::cerr << result[i] << " ";
std::cerr << std::endl;
}
Have you perhaps double defined your results array in a couple places and then accidently refered to one copy in one place and another copy elsewhere? Perhaps the second is a pointer and not an array and that is why the debugger is confused?
To ensure this problem doesn't occur, you should never use global variables like that. If you absolutely must have one, put it in a namespace for clarity.