Matrix parameter passing error

Asked

Viewed 410 times

8

I am trying to understand the function of pointers for an array. For this, I have elaborated the small program below. I made some mistake, because, in the indicated line, error is occurring (Segmentation fault).

What is the correct way to pass the pointer that points to an array, as I tried in the example?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    float t1[4][2];
    for (i=0;i<8;i++)
    {
        t1[i%4][i%2]=i+1;
    }
    teste1(t1);
    getchar();
    return 0;
}
void teste1(float ** t1)
{
    int i;
    for (i=0;i<8;i++)
    {
        printf("%f\t",t1[i%4][i%2]);   // Erro nesta linha ("segmentation fault")
    }
}

1 answer

9


The problem is in the parameter declaration in the function teste1. If you are passing a two-dimensional * array* (4X2) of the type float, then the function should receive the same type in the parameter.

Actually the code didn’t even compile. In addition to not recognizing the function teste1 there was incompatibility of types in the parameter. You’re probably using a compiler that doesn’t meet the language’s standards, so you were able to compile. Or the actual code you compiled is different from the one posted.

I reversed the two functions so that the teste1 is declared/defined before being used. I could also just declare before and set after but I think the code gets dirtier like this.

I also arranged the calculation of the second index that was wrong as indicated in the comments:

#include <stdio.h>
#include <stdlib.h>

void teste1(float t1[4][1]) {
    for (int i = 0; i < 8; i++) printf("%f\t", t1[i % 4 ][i / 4]);
}
int main() {
    float t1[4][2];
    for (int i = 0; i < 8; i++) t1[i % 4][i / 4] = i + 1;
    teste1(t1);
    getchar();
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

In the comment it was said to leave generic. This is possible with arrays if using a compiler that meets the C99 standard (the GCC allows until the dimensions sizes can be passed after the array). The header of the function would have to look like this:

void teste1(int m, int n, float t1[m][n]) {

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

But if you really want to use a pointer as a parameter and want to generalize you have to do this:

In this case the teste1 is receiving as pointer (not pointer to pointer).

The element position calculation is being done manually since it is being treated with pointer and not array.

The call also needs to make a casting to suit the type of array pointer.

And there are also parameters to receive the total rows and columns of the matrix.

I also used #define to avoid getting lost when changes the size of the matrix

#include <stdio.h>
#include <stdlib.h>

#define linhas 4
#define colunas 2

void teste1(float * t1, int totalLinhas, int totalColunas) {
    for (int i = 0; i < totalLinhas* totalColunas; i++) printf("%f\t", *((t1 + (i % totalLinhas) * totalColunas) + (i / totalLinhas)));
}
int main() {
    float t1[linhas][colunas];
    for (int i = 0; i < linhas * colunas; i++) t1[i % linhas][i / linhas] = i + 1;
    teste1((float *)t1, linhas, colunas);
    getchar();
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • Thanks! I used this form (without indication of the dimensions) because I was thinking of use with varied dimensions. The solution you were looking for is the second. The code was transcribed exactly as I compiled it. I am using Codeblocks (version 13.12 - Windows Unicode - 32bits). I could not increase the score of this answer, because I still have insufficient score to vote.

  • This code does not work for varying dimensions, I’ll put another one that works. Codeblocks is not a compiler is an IDE. You have to see which compiler it is using. It can be build parameters. I only compile with maximum security on, so the compiler does not allow to do things that work in one situation and another not. Look at the [tour], you can accept the right answer to your question every time (you don’t have to do it already) and I think you already have a reputation to vote on now.

  • One thing I didn’t understand, after seeing the code working, is that I expected it to be written 1,2,...8 in stdout and not 5,6,7,8,5,6,7,8. What I did wrong?

  • See http://ideone.com/I4m9EU The problem is in this other account, it is not resulting in what you expect. The answer is according to what you did, see this code here in the comment if it is what you want.

  • It was just a test. But I was thinking about it. Before seeing this last post, I did it like this: http://ideone.com/c4XFWD

  • I edited the question. I added a code that the compiler accepts well, but it provides some strange results, with matrix of type int (exchange row for columns apparently). If you switch to float, it also compiles, but provides zero results.

  • In decent compiler this code does not compile. I don’t work with bad compilers: http://ideone.com/defIl7. If you insist on it you will learn wrong and suffer further. Anyway this is another code, another problem, so it must be another question. Enter your compiler in it.

  • I don’t have much time today. Do what I told you, ask another question and I will try to answer, or someone else will be able to answer.

  • 2

    Here is a small program for multiplication of two matrices, from the orientations that Bigown has passed, and other experiments that I tried: I used two routines for multiplication: one using pointer arithmetic and another indices: http://ideone.com/7DnFwe

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.