Ganjira
Ganjira

Reputation: 976

Converting int to char*

I'm creating a matrix which will be multiplied by another one. The matrix will get the values from the arguments (*argv[]).

Until now I created something like this:

for(int i=0; i<2; i++) {
       for(int j=0; j<2; j++) {
          sec[i][j]=argv[gv];
          gv++;
       }
    }

for(int i=0; i<2; i++) {
   for(int j=0; j<2; j++) {
      int a = (int)fir[i][j];
      int b = (int)sec[i][j];
      int r = a*b;
      res[i][j]=(char)(r); //the problem is here
   }
   cout<<endl;
}

The problem is that my code crashes when I want to show the matrix. The problem can be in the marked place.

Any ideas how to solve that simple problem? :)

Thanks in advance!

Upvotes: 0

Views: 441

Answers (2)

mikyra
mikyra

Reputation: 10347

The problem you asked about

As you didn't show any declarations I can't tell for sure, but if the crash occurs at the indicated position most probably you didn't reserve enough space for res. Are your sure you declared it like this?

char res[2][2];

Other problems

I'm not really sure what you are trying to do in the first loop, but if if the the identifier argv references a parameter passed to main like in:

int main (int argc, char *argv[])

argv will be an array of pointers to strings not an array of the value of the first character contained in those strings. So you'll be filling your sec array with more or less random values chosen by your OS and the ABI it adheres to to store the parameters passed to your function at that location.

Essentially your setup looks like this:

                               +---------> "my_program"
 argv -> +--------------+     /              @ anywhere in memory
         | argv [0]    ------+
         +--------------+          +---->  "paramter argc-2"
         | argv [1]    ---------+ /          @ another location in memory
         +--------------+        \
         | ...          |      /   +-----> "paramter 1"
         +--------------+     /              @ some other location again
         | argv[argc-1] |----+
         +--------------+

While it is those @ locations you are performing your calculations with.

Don't misinterpret << output

While using constructs like

std::cout << argv[1]

will produce the same output as:

std::cout << 12

if you called your program with 12 as the first parameter both seem to be more or less identical they are definately not! As it is just the overloaded << that makes them appear to be almost the same.

Nevertheless << will toggle much different code when called on an object of type char* as is toggled, when run on an object of type int.

The difference by Example

You might want to check with the following snippet to see the difference in action:

#include <iostream>
#include <stdio.h>

int main (int argc, char *argv[]) {
  int k;

  for (k=0; k<argc; ++k)
    std::cout << k << ": " << argv[k] << "\n";

  for (k=0; k<argc; ++k)
    printf ("%d: %d\n", k, (int) argv[k]);

  return 0;
}

Running the generated code with ./my_program 12 27 42 will produce output like the following:

0: ./my_program
1: 12
2: 27
3: 42

0: -1079747848
1: -1079747840
2: -1079747837
3: -1079747834 

Quite a difference, which results from the fact that when faced with a value of type char* << "knows" it has to perform a different action than when faced with a value of type int.

By "telling" the implementation in the second loop the right action to perform:

  for (k=0; k<argc; ++k)
    printf ("%d: %s\n", k, argv[k]);

You'll get the same output from the second loop.

Those strange numbers of the first output just resulted from interpreting the bitpatterns used to represent pointers to paramters passed to main as those (bitpatterns) of integers.

Typecasting to (unsigned) instead and using "%x" instead of "%d" would have made this even more obvious giving something like the following output:

0: bf92bae9
1: bf92baf6
2: bf92baf9
3: bf92bafc

As you can see I "cheated" a little bit in my picture by exaggerating the randomness of memory locations.

If you count indices of you'll find in this example the OS just placed the parameters (including termination \0 characters) just one after the other.

Upvotes: 3

Parker Kemp
Parker Kemp

Reputation: 765

As Serdalis said, if you're just trying to output ints, there's no need to convert them; just send them to cout.

Converting an int to a char will likely not do what you want anyway. chars in C are numerical values anyway, and they convert by ASCII values. If you're determined to turn them into strings, you can use itoa:

itoa(r, res[i][j], 10);

This is also assuming res is a 2D array of char*s, which I don't know since you didn't provide the declaration. If it is, they will need to be dynamically allocated before you do this.

Upvotes: 0

Related Questions