The question I am trying to ask is how do I not only initialize a variable length matrix inside a function but also to return it from that same function.
I have figured out solutions that work but they are not quite what i am looking for.
To more visualize what I am asking is to show my solutions or attempts at solving the problem.
My first idea was what if I made an array of pointers
#include <stdio.h>
int main(){
int value = 12;
int value1 = 32;
int *mat[2] =
{
&value,
&value1
};
printf("%d",mat[0][1]);
}
This works but is very limited obviously not even a matrix; as the pointers inside just point to a value instead of them being an array its more like an array of values just with extra steps
So instead I thought what if i did something similar but fix the problem of arrays by making each index an array themselves.
#include <stdio.h>
int **mfoo(int x, int y){
int **matrix;
int *arry[y];
int arry1[x];
for(int i=y;i<y;i ){
arry[i] = arry1;
}
matrix = arry;
return matrix;
}
int main(){
int **mat = mfoo(5,5);
mat[0][3] = 5;
printf("%d",mat[0][3]);
return 0;
}
This obviously will not work as the address of the first index of arry[x] is being assigned to each index in the matrix making it so that each index of the matrix is exactly the same array.
As predicted it works for the first index of mat like mat[0][3] But it will end Segmentation fault if I try to then index the second index of mat mat[1][3] which seems odd to me because it should just refer itself to the same array since mat[0] and mat[1] should be the same address as they both point to &arry1[0]?
my next idea is the only one I have gotten to work and I will show it now inside of a function I made to parse a string into arguments
char * pipe_arguments(char *str, int j){
int _j=0;
int _i=0;
char *argument_ptr;
char arr[20][200];
for(int i=0; i<j; i ){
if(str[i] > 32 && str[i] < 127){
arr[_i][_j] = str[i];
_j ;
}
else if(str[i] == 32){
_i ;
}
}
argument_ptr = arr[0];
//"echo -o A_String" -- should see three parameters
return argument_ptr;
}
int main(){
char str[] = "echo -f filename.txt -o stdout";
char *ptr;
ptr = pipe_arguments(str, sizeof(str));
for(int j=0;j<20;j ){
for(int i=0;i<200;i ){
printf("%c",*ptr );
}
printf("\n");
}
}
This works completely fine and prints out almost what I want except for some very random characters
An example of the output of this function would be
echo
-f
filename.txt
-o
stdout�y�~���
�Pk�y�~p`j`jp>�>`�>�
?p
p�y�~�y�~`�p`�
A�y�~�p�y�~/�j�Unnert/usr/li���y�~�y�~��Gļy�~��h�y�~�J�y�~Z�~y�~=�y�~�
��F7@�y�~p�y�~�j�U�P�F7�P��qZ�_qZ�_%�aD��
�j�Up�y�~`�y�~��y�~�
p�y�~ ���p�y�~�
@�h�y�~�y�~�y�~�y�~@8
@IH�V�y�~�
s~y�~�}y�~8S�y�~�~��h�y�~��y�~�y�~�y�~�y�~
�V�y�~��t~y�~x}y�~8S�y�~�~�~��~��y�~�y�~�ﵽ��y�~(�@�y�~�y�~��y�~@�y�~
�y�~�t~y�~���y�~���SP�y�~�U�y�~�y�~(U�y�~`�jɽy�~��y�~0�y�~
�j�U�SP�y�~|�c;̸U�y�~�jɽy�~�y�~`�y�~0N�y�~��~}y�~��y�~�h�y�~�p�y�~���
////////////////�����usr/lib/i386-lin��y�~��y�~@�y�~@�y�~}~�0�y�~0�y�~
� �y�~ �y�~
��T�y�~�y���y�~��y�~�Ѣ�y�~@�y�~P�y�~Y�y�~�y�~H�y�~0@j�Up
�Z�y�~�'P�#�y�~@�y�~�y�~�@p�y%2@j�U0�A@
|wn]@�y�~��j�U��y�~ �?8�y�~�"�y�~b`�!�
�`2@j�U!�y�~`�y�~`�y�~�f-`�y�~h
�j�U���y�~`�y�~�
You can see it parses the strings and put each string into one of the indexes but right after starts spitting out random gibberish.
This has nothing to do with the question at hand but would be appreciated if answered as to why it does this as well?
Anyways, this solution works using a linear pointer and indexes through the array using pointer arithmetic.
There still feels like something is unsolved its not quite what I want, I feel like there should be a solution without the use of malloc or calloc. And I dont mean make these functions yourself and then use them I mean there just feels like theres a way to get a double pointer as a result and being to index the matrix using mat[4][10] for example.
CodePudding user response:
You can't do this (see https://en.cppreference.com/w/c/language/scope):
char* func()
{
char arr[1][2]; //local scope
return &arr[0]; //error, the array will no longer exist (out of scope)
}
If you don't want to allocate memory within the function, then you have to provide another storage as parameter, like:
char** func(char **matrix, size_t rows, size_t cols /* ,other args */)
{
/* do something */
return matrix;
}
int main()
{
char matrix[20][200];
func(matrix, 20, 200);
return 0;
}
There is another possible solution but only appropriate for smaller datatypes (to avoid unnecessary copy and stack usage), like:
struct matrix {
char data[2][2];
};
struct matrix func(char a, char b, char c, char d)
{
struct matrix m = { .data = {{a, b}, {c, d}} }; //initialize matrix
return m; //return on stack
}
int main()
{
struct matrix m = func('a', 'b', 'c', 'd');
printf(
"%c %c %c %c\n",
m.data[0][0],
m.data[0][1],
m.data[1][0],
m.data[1][1]
);
return 0;
}
As long as the datatype (struct) is complete (therefore its size is known at compile time), there should be no problem to return such struct from a function (i don't know the limits on the max size of such struct).
