0

I was creating a function that would give me random values of a matrix. I know how to make it in the main function but I want a separate one. I also tried with void and the same thing happened, and I keep getting the same error. I am beginner and I understand that the issue is something to do with pointers but I still don't know what should I do to make it work and fix it. I already Googled it but I can't make this work.

#include<stdlib.h>
#include<iostream> 
#include<time.h>

int row, coll;

int random(int *mat[])
{
    srand(time(0));
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<coll; j++)
        {
            mat[i][j] = rand()%10;
        }
    }

}

main()
{
    std::cin >> row >> coll;
    int mat[row][coll];
    random(mat);
} 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 8
    `std::cin >> row >> coll; int mat[row][coll];` -- This is not valid C++. Arrays in C++ must have their dimensions specified by a compile-time expression, not runtime variables. – PaulMcKenzie Nov 25 '20 at 17:41
  • 3
    Arrays are not pointers. In particular, an array of arrays is not an array of pointers. – molbdnilo Nov 25 '20 at 17:42
  • Nor is it valid C, for although C has variable-length arrays (as an optional feature), it does not have iostream. – John Bollinger Nov 25 '20 at 17:43
  • Cannot be done. All but the outer-most dimension must be known by `random` at compile time. This is not possible with a Variable Length Array. One of many reasons that they [are not included in Standard C++](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard). May I recommend [a simple matrix class backed by a `std::vector`](https://stackoverflow.com/a/2076668/4581301)? – user4581301 Nov 25 '20 at 17:43
  • *i am beginner and i get it that the issue is something to do with pointers* -- No good C++ book shows arrays declared like this, so you must be getting your information from a very bad website. – PaulMcKenzie Nov 25 '20 at 17:44
  • @PaulMcKenzie Sure, it's not valid C++ according to the standard, but big compilers like g++ and clang++ supports it. So it's not likely the source of OP:s problem. – klutt Nov 25 '20 at 17:48
  • To expand on Paul's point, very bad websites unfortunately make up most of the programming advice on the Internet. It's only by dumb luck that you stumble across a good one with a web search unless you already almost know what you're looking for. C++ is particularly unforgiving, so prefer to learn it a structured environment [with a good set of reference materials](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – user4581301 Nov 25 '20 at 17:50
  • @klutt how though? dynamic sized arrays are not supported in that syntax as far as I know, even if it is a compiler specific thing, doesn't it need to be explicitly `delete`d? How does that work, seems like a ticking bomb full of memory leaks – WARhead Nov 25 '20 at 17:52
  • @WARhead I don't know the details. I suspect it's the same as in C, which means that they are allocated on the stack and automatically freed. I have a really hard time believing you are supposed to free them. – klutt Nov 25 '20 at 17:53
  • @klutt Big compiler's such as Visual C++ do not support them. The OP is just lucky he is using a compiler that (unfortunately IMO) has the "use VLA" switch automatically set to "on" when compiling. In addition, VLA's were broken in various versions of g++ when it came to using them as iterators in various STL algorithms. Supposedly this has been fixed. – PaulMcKenzie Nov 25 '20 at 17:56
  • @klutt I thought the size of max size of stack for a function must be known at compile time. I honestly didn't know about such a feature. – WARhead Nov 25 '20 at 17:58
  • @PaulMcKenzie I'm just saying that it's not an extremely rare thing that only obscure compilers use. It's not really worth pointing out that someones code does not strictly conform to the standard just because it's using compiler extensions. – klutt Nov 25 '20 at 17:58
  • @WARhead This answer I wrote is about C. I have no reason to believe it's different in C++, but I cannot promise anything. But it may clarify how they work. https://stackoverflow.com/a/58163652/6699433 – klutt Nov 25 '20 at 18:00
  • @WARhead But no, there are no such requirements per se. Stack allocation is basically just done by incrementing the stackpointer to the size you want. You can use `alloca()` for that in both C and C++. – klutt Nov 25 '20 at 18:01
  • @klutt it is worth to point that out, because complete beginners are mislead by certain "tutorial" websites that such complier extensions would be proper C++. They write non-portable code and are puzzled why it does not work everywhere. Imho it is obscure what gcc uses as default settings – 463035818_is_not_an_ai Nov 25 '20 at 18:06
  • @idclev463035818 True, but then you should also explain what compiler extension means. Just saying that it's not valid C++ is only confusing for a beginner. How would you react when you were a beginner if someone said that your code that compiles just fine isn't valid? – klutt Nov 25 '20 at 18:21
  • @klutt you make a very good point. Usually I point to [this](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard), but I have to admit that I don't do that always. Thanks for reminding me ;) – 463035818_is_not_an_ai Nov 25 '20 at 18:26
  • take a look at this [Why aren't variable-length arrays part of the C++ standard?](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard). vlas are a compiler extension, but actually you don't really need them in c++ – 463035818_is_not_an_ai Nov 25 '20 at 18:27
  • @idclev463035818 The need is bigger in C, but you don't need them there either. :) – klutt Nov 25 '20 at 18:30
  • @klutt i remember a good answer that explained what they are good for in C. If i understood it correctly, the use case was rather special and not just for any array whose size is only known at runtime (but thats what certain "turorial" sites encourage) – 463035818_is_not_an_ai Nov 25 '20 at 18:34
  • @idclev463035818 I would never use a VLA in C unless I have a good reason. A good reason is that I have very limited memory resources, so I cannot use a static array AND I need the extra performance by skipping a malloc call. If those two are fulfilled, I'd consider using a VLA. – klutt Nov 25 '20 at 18:34
  • @idclev463035818 But then again, then I would use a pointer and a `alloca` call instead just to remind me that VLA:s are bad – klutt Nov 25 '20 at 18:36
  • 2
    @klutt you don't have to convince me. I'm a `std::vector` fanboy and I never write any C ;) – 463035818_is_not_an_ai Nov 25 '20 at 18:37

2 Answers2

2

You are trying to mix features of two different languages in one program.

The presented program is not a valid C++ program nor a valid C program.

For example variable length arrays as in your program

std::cin >> row >> coll;
int mat[row][coll];

is not a standard C++ feature.

The function main shall have the return type int.

Your function random

int random(int *mat[])

has the return type int but returns nothing.

The argument has the type (if to assume that variable length arrays are supported)

int ( * )[coll]

but the function parameter type is

int **.

If you are going to write a C++ program then instead of a variable length array use the standard container std::vector<std::vector<int>>.

For example

std::cin >> row >> coll;

std::vector<std::vector<int>> mat( row, std::vector<int>( coll ) );

Otherwise write a C program that can look like

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

void random( size_t row, size_t col, int mat[row][col], int limit )
{
    srand( ( unsigned int )time( NULL ) );
    
    for ( size_t i = 0; i < row; i++ )
    {
        for ( size_t j = 0; j < col; j++ )
        {
            mat[i][j] = rand() % limit;
        }
    }
}

int main( void ) 
{
    size_t row, col;
    
    scanf( "%zu %zu", &row, &col );
    
    int mat[row][col];
    
    random( row, col, mat, 10 );
    
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Okay, so i tried to do what you told me to, i tried the C method because i still dont know how to use vector, and now i get another message that the error is at for ( size_t j = 0; j < col; j++ ) { mat[i][j] = rand() % limit; } It says that expression must have pointer to object type, i know that this is probably something simple but i am beginner and i know that i dont know a lot of stuff but thank you for your help. – Dimitrije Djokic Nov 25 '20 at 21:13
  • @DimitrijeDjokic I showed a demonstrative program that compiles and works. Copy and paste it. – Vlad from Moscow Nov 25 '20 at 21:25
  • I get one error that says that parameter is not allowed, in function where its void random(int mat[row][col]) row and col are underlined. – Dimitrije Djokic Nov 25 '20 at 23:04
  • I was studying for past 3 hours, i tried so many different things, watched a lot of tutorials but i keep getting message "cannot convert 'int(*)[col]....etc.". Even in your code, that is the only error message i am getting i managed to figure out everything else. I just dont know why this specific thing happens to me, i tried doing step by step something that someone did and i get the same error over and over again, like i said even with your code, i know why i got other errors, i fixed those. I am repeating myself here but okay. Thank you for your help once again. – Dimitrije Djokic Nov 26 '20 at 02:51
  • @DimitrijeDjokic The C compiler should support the C99 Standard. – Vlad from Moscow Nov 26 '20 at 08:12
  • I finally got rid of issue, i am so tired, and the issue was something to do with C99 so i reinstalled everything and your C code works just fine, i also studied vectors for 1-2 hours and i made a function that randoms vector and one that prints vector, using ```vector> name``` just like you told me to do, and that works also just fine, vectors are really interesting and there is a lot i can learn. Thank you once more. – Dimitrije Djokic Nov 26 '20 at 12:41
0

I wrote a simple struct of matrix for you to carry the data around functions. Also, a output overload to make it easier to demo. Please look over it, and don't hesitate to ask, if you need more elaborations.

#include<stdlib.h>
#include<iostream>
#include<time.h>
#include <iomanip>
struct Matrix
{
    int *arr;
    const int row, col;
    Matrix() = delete;
    Matrix(const int i, const int j): row(i), col(j)
     {
       arr = new int [i*j];
     }
   ~Matrix() { delete [] arr; }
   int operator()(const int i, const int j) const {return arr[i*col+j];}
   int&operator()(const int i, const int j) {return arr[i*col+j];}
};
std::ostream& operator<<(std::ostream&osm, const Matrix&M)
{
    for (int i=0; i<M.row; i++) {
        for (int j=0; j< M.col; j++)  osm << std::setw(8) << M(i,j);
        osm << std::endl;
    }
    return osm;
}
void random(Matrix& amtx)
{
   srand(time(0));
   for(int i=0; i<amtx.row; i++)
    {
       for(int j=0; j<amtx.col; j++)
        {
           amtx(i,j) = rand()%10;
        }
    }
}
int main()
{
    int r, c;
    std::cout << "Input row and column : ";
    std::cin >> r >> c;
    Matrix mtx(r, c);
    random(mtx);
    std::cout << mtx;
   return 0;
}

and the test run:

Input row and column :  5  5
      6       3       1       9       3
      6       5       1       4       1
      1       2       7       5       5
      9       3       2       8       1
      7       4       8       3       5
ytlu
  • 412
  • 4
  • 9
  • Headed in the right direction, but `Matrix` leaks memory . When you fix the leak by adding a destructor, you will have to observe either [the Rule of Three or the Rule of Five](https://en.cppreference.com/w/cpp/language/rule_of_three). – user4581301 Nov 25 '20 at 19:14
  • This is too complicated for me :D i am beginner and i dont know how this method functions. Thank you for your help tho :D have a nice day. – Dimitrije Djokic Nov 25 '20 at 21:15
  • @user4581301 I forgot to add the destrcutor. Edited. – ytlu Nov 26 '20 at 04:04