-4

The following code builds perfectly well and runs on Turbo C++. I build the same on MSVC2010, it builds without error, but when I run it (run without debug), It shows

An unhandled win32 exception occurred in gentic.exe

Also during debugging it shows :

Unhandled exception at 0x00411672 in genetic.exe: 0xC0000005: Access violation writing location 0xcccccccc.

This occurs after I input row and columns... at *dat2=(double *)malloc(r*sizeof(double*));(yellow arrow is now pointing these lines)

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
class genetic
{
public:
  int i,j,m,n;
  double **dat2,**dat;
  double** createarray(int r,int c)
  { int i;
    *dat2=(double *)malloc(r*sizeof(double*));
    for(i=0;i<r;i++)
      {
        dat2[i]=(double*)malloc(c*sizeof(double));
      }
    return dat2;

  }
  void input()
  {
    printf("enter rows \n");
    scanf("%d",&m);
    printf("enter cols \n");
    scanf("%d",&n);
    dat=createarray(m,n);

    for(i=0;i<m;i++)
      {
        for(j=0;j<n;j++)
          {
            double val;
            scanf("%lf",&val);
            dat[i][j]=val;
          }
      }
  }
  void output()
  {
    for(i=0;i<m;i++)
      {
        for(j=0;j<n;j++)

          {
            printf("%3lf  ",dat[i][j]);
          }
        printf("\n");

      }


  }
};

void main()
{
  genetic g1;
  g1.input();
  g1.output();
  getch();

}

Any idea why this diffrent behavior in MSVC and how do we solve this issue?

Update:

As suggested I changed to :

 double** createarray(int r,int c)
 { int i;
 double **dat2;
  dat2=(double *)malloc(r*sizeof(double*));
for(i=0;i<r;i++)
 {
 dat2[i]=(double*)malloc(c*sizeof(double));
 }
return dat2;

 }

But still I am facing problem:

Error 1 error C2440: '=' : cannot convert from 'double ' to 'double *'

gpuguy
  • 4,607
  • 17
  • 67
  • 125
  • What does your debugger tell you? (don't say that you didn't use the debugger to step through your code!) – abelenky Jul 16 '13 at 04:12
  • 1
    `void main` burns my soul. There is no excuse to use Turbo when there are perfectly modern working free compilers. – chris Jul 16 '13 at 04:15
  • 1
    At least IMO, this code is not worth saving. At least in my opinion, you should throw out your current code and use `std::vector` to store your data. While you're at it, you probably want to use `cin` and `cout` for your input and output as well. – Jerry Coffin Jul 16 '13 at 04:17
  • Please don't use `void main` - it's not standard legal C89 or C++. Actually, please just don't use Turbo while you're at it. – Iskar Jarak Jul 16 '13 at 04:44
  • @chris: "There is no excuse to use Turbo" That's kinda narrow-minded. If you somehow run into old C program you need to fix that, for example, uses borland graphic interface, then you might get a perfect reason to use Turbo C. Where I live cash registers run FreeDOS, so such scenario is possible. – SigTerm Jul 16 '13 at 05:33
  • @SigTerm, Fair enough, but it's extremely painful to see code produced by that monster. I'm sure it wasn't quite so bad back when it was modern, but time has really aged it. – chris Jul 16 '13 at 05:41
  • [0xCC indicates uninialized memory](http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new) which is a useful debugging feature of MSVC. And don't tag both C and C++, they're different languages. You [don't cast the result of malloc in C but it's necessary in C++](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – phuclv Mar 04 '15 at 08:09
  • and don't use [Turbo C](http://stackoverflow.com/questions/3920351/what-is-wrong-with-using-turbo-c)/[Turbo C++](http://stackoverflow.com/questions/1961828/why-not-to-use-turbo-c) anymore – phuclv Mar 04 '15 at 08:24

4 Answers4

4

This line is incorrect:

    *dat2=(double *)malloc(r*sizeof(double*));

Since you haven't assigned anything to dat2, you can't dereference it. It should be:

    dat2=(double **)malloc(r*sizeof(double*));

Also, since dat2 isn't used outside the createarray function, it would be better to declare it locally within it.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I did double **dat2; in createarray(), still I am having Error 1 error C2440: '=' : cannot convert from 'double *' to 'double **' – gpuguy Jul 16 '13 at 04:24
  • 1
    I fixed the cast in my answer. Is this C or C++? If it's C, you shouldn't cast the result of `malloc()` at all. – Barmar Jul 16 '13 at 04:26
1

You need to get rid of the first * in the line you quote:

*dat2=(double *)malloc(r*sizeof(double*));

EDIT:

Should be:

dat2=(double **)malloc(r*sizeof(double*));

or better:

dat2 = new double*[r];

Crowman
  • 25,242
  • 5
  • 48
  • 56
  • Ok. But can you explain why so? – gpuguy Jul 16 '13 at 04:12
  • Also when I did this dat2=(double *)malloc(r*sizeof(double*));, I get : Error 1 error C2440: '=' : cannot convert from 'double *' to 'double **' – gpuguy Jul 16 '13 at 04:14
  • @PaulGriffiths: Better still, use `std::vector` since this is C++ *and* it's not 1995 any more. – Jerry Coffin Jul 16 '13 at 04:39
  • @JerryCoffin: Agreed, other than as an exercise in dynamically allocating manually - the quality of the original code suggests that you can't learn all of C++ in a day, after all - `std::vector` would be the best choice. – Crowman Jul 16 '13 at 04:50
0

because dat2 varaible is uninitialized, and you're writing into its address within "createarray".

YOu probably wanted to use something like

 dat2=(double *)malloc(r*sizeof(double*));

Here's why it happens:

Dereferencing unintialized pointer is undefined behavior.

Turbo C can compile "real mode" programs. In real mode you can write into some random memory locations and in MANY(or most) cases nothing noticeable will immediately happen unless you're really unlucky.

MSVC compiles protected mode programs. In protected mode most attempts to access random memory address will crash program.

SigTerm
  • 26,089
  • 6
  • 66
  • 115
0

This line

*dat2=(double *)malloc(r*sizeof(double*));

has an extra * at the beginning.

When you execute malloc, you are given a void* as a result which points to the newly allocated memory (not considering error conditions). You correctly casted this value to a double*, then incorrectly assigned the value to a double (namely *dat2, which means "the variable pointed by dat2"). Instead, you should have assigned it to a variable of type double*, namely dat2.

Don't get confused from it working (meaning it doesn't crash) on TurboC, it's by pure chance.

Stefano Falasca
  • 8,837
  • 2
  • 18
  • 24