Passing 2D array by reference

Started by
7 comments, last by deathkrush 17 years, 6 months ago
What is the syntax for passing a 2D array (static) by reference? I tried the following but it seems to be passing by value. int a[][2] = { { 1, 2 }, { 3, 4 } }; void foo(int param[][2]) {} foo(a); And void foo(int &param[][2]) {} doesn't work...
Advertisement
#include <stdio.h>

int a[][2] = { { 1, 2 }, { 3, 4 } };

void foo(int param[][2]) {
param[0][0] = 5;
}

int main(){
foo(a);
printf("%d\n", a[0][0]);
}

It should print 5, so it's definitely not passing by value. In C static arrays are implemented using pointers, so they are passed by pointer.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
Quote:Original post by deathkrush
#include <stdio.h>

int a[][2] = { { 1, 2 }, { 3, 4 } };

void foo(int param[][2]) {
param[0][0] = 5;
}

int main(){
foo(a);
printf("%d\n", a[0][0]);
}

It should print 5, so it's definitely not passing by value. In C static arrays are implemented using pointers, so they are passed by pointer.


Oh... You're right. I have no idea why it didn't work for me.

But this brings another question:
How do I pass it by value then?
I'm pretty much a novice, but I would suggest to pass by value:

foo(&a)

Again, i'm a novice. However, it seems to me that you want to pass the entire array to the function. If that is the case, I would suggest a wrapper. If you can't do a wrapper, try this:

#include <stdio.h>

int a[][2] = { { 1, 2 }, { 3, 4 } };

void foo(int *param[][2]) {
param[0][0] = 5;
}

int main(){
foo(&a);
printf("%d\n", a[0][0]);
}

Let me know how it turns out ... I haven't actually tried the above method, but it might actually work.


~Argonaut________________________________Why "~Argonaut"? It's all just a mathematical expression denoting a close approximation of "Argonaut", which is irrational and can't be precisely defined.
Quote:Original post by argonaut
I'm pretty much a novice, but I would suggest to pass by value:

foo(&a)

Again, i'm a novice. However, it seems to me that you want to pass the entire array to the function. If that is the case, I would suggest a wrapper. If you can't do a wrapper, try this:

#include <stdio.h>

int a[][2] = { { 1, 2 }, { 3, 4 } };

void foo(int *param[][2]) {
param[0][0] = 5;
}

int main(){
foo(&a);
printf("%d\n", a[0][0]);
}

Let me know how it turns out ... I haven't actually tried the above method, but it might actually work.


Ok, you're confusing me. Why would foo(&a) be passing by value? It seems more like passing "the reference of the pointer to the array."

I haven't had the chance to test it yet, but it just look kinda odd to me.
You cannot pass c-style arrays by value. You can either make them const to prevent accidental manipulation, or make them in a small structure and pass that by value.

Or just use std::vector for all you array-like needs.

If you have boost, try boost::array.
Quote:Original post by rip-off
You cannot pass c-style arrays by value. You can either make them const to prevent accidental manipulation, or make them in a small structure and pass that by value.

Or just use std::vector for all you array-like needs.

If you have boost, try boost::array.


Thanks for the clarification.
You can pass them by reference to keep sizing information:

template< class T, size_t D1, size_t D2 >void Do( T ( &arr )[D1][D2] ) {  arr[D1 / 2][D2 / 2] = 1;}int main() {  int arr[4][6] = { 0 };  Do( arr );}



Although, you would be better off using std::vector, boost::array or boost::multi_array, as rip-off mentioned.
Here is how I would approach passing by value:

#include <iostream>template <class T, int s>class Array{	T array;<br><br><span class="cpp-keyword">public</span>:<br><br>	Array(<span class="cpp-keyword">const</span> T t)<br>	{<br>		<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i=<span class="cpp-number">0</span>; i&lt;s; i++)<br>			array<span style="font-weight:bold;"> = t<span style="font-weight:bold;">;<br>	}<br><br>	Array(<span class="cpp-keyword">const</span> Array&amp; t)<br>	{<br>		<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i=<span class="cpp-number">0</span>; i&lt;s; i++)<br>			array<span style="font-weight:bold;"> = t<span style="font-weight:bold;">;<br>	}<br><br>	T&amp; <span class="cpp-keyword">operator</span>[](<span class="cpp-keyword">int</span> i)<br>	{<br>		<span class="cpp-keyword">return</span> array<span style="font-weight:bold;">;<br>	}<br><br>	<span class="cpp-keyword">const</span> T&amp; <span class="cpp-keyword">operator</span>[](<span class="cpp-keyword">int</span> i) <span class="cpp-keyword">const</span><br>	{<br>		<span class="cpp-keyword">return</span> array<span style="font-weight:bold;">;<br>	}<br>};<br><br><span class="cpp-keyword">template</span> &lt;<span class="cpp-keyword">class</span> T, <span class="cpp-keyword">int</span> s&gt;<br>std::ostream&amp; <span class="cpp-keyword">operator</span>&lt;&lt;(std::ostream&amp; str, <span class="cpp-keyword">const</span> Array&lt;T,s&gt;&amp; a)<br>{<br>	<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i=<span class="cpp-number">0</span>; i&lt;<span class="cpp-number">4</span>; i++)<br>		str &lt;&lt; a<span style="font-weight:bold;"> &lt;&lt; <span class="cpp-literal">" "</span>;<br><br>	<span class="cpp-keyword">return</span> str;<br>}<br><br><span class="cpp-comment">//An equivalent of memset, passes arrays by value</span><br><span class="cpp-keyword">template</span> &lt;<span class="cpp-keyword">class</span> T, <span class="cpp-keyword">int</span> s&gt;<br><span class="cpp-keyword">void</span> MemSetByVal(Array&lt;T, s&gt; a, T v)<br>{<br>	<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i=<span class="cpp-number">0</span>; i&lt;s; i++)<br>		a<span style="font-weight:bold;"> = v;<br>	<span class="cpp-keyword">return</span>;<br>}<br><br><span class="cpp-comment">//An equivalent of memset, passes arrays by reference</span><br><span class="cpp-keyword">template</span> &lt;<span class="cpp-keyword">class</span> T, <span class="cpp-keyword">int</span> s&gt;<br><span class="cpp-keyword">void</span> MemSetByRef(Array&lt;T, s&gt; &amp;a, T v)<br>{<br>	<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i=<span class="cpp-number">0</span>; i&lt;s; i++)<br>		a<span style="font-weight:bold;"> = v;<br>	<span class="cpp-keyword">return</span>;<br>}<br><br><span class="cpp-keyword">int</span> main()<br>{<br>	<span class="cpp-keyword">int</span> arrayInit[] = {<span class="cpp-number">1</span>, <span class="cpp-number">2</span>, <span class="cpp-number">3</span>, <span class="cpp-number">4</span>};<br>	Array&lt;<span class="cpp-keyword">int</span>, <span class="cpp-number">4</span>&gt; a = arrayInit;<br><br>	MemSetByVal(a, <span class="cpp-number">0</span>);<br><br>	std::cout &lt;&lt; a &lt;&lt; <span class="cpp-literal">"\n"</span>;<br><br>	MemSetByRef(a, <span class="cpp-number">0</span>);<br><br>	std::cout &lt;&lt; a &lt;&lt; <span class="cpp-literal">"\n"</span>;<br>}<br><br><br></pre></div><!–ENDSCRIPT–><br><br>It should print <br>1 2 3 4<br>0 0 0 0<br><br>because MemSetByVal doesn't do anything to the array, but MemSetByRef does. boost::array already does all of that, but if you don't want to use boost, there is nothing wrong with writing a custom array wrapper, at least you will get to practice writing templates.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)

This topic is closed to new replies.

Advertisement