Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Dakar

An annoying problem

This topic is 5217 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been working on a program to find factors of a number and compare it with another, and the first part (finding the factors) worked pretty well. Now, I'm trying to store them, and I have the following code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

int *divide(int it, int *keeper);

int main()      //makes a divider program

{
  int divident;
  int *list;
  int *listo;
  cout << "This program divides a number by several others and shows the results.\n What shall the number be?";
  cin >> divident;
  cout << "\n";
  divide(divident, list);
  cout << list[1]; // to make sure it works

  system("PAUSE");
  return 0;
}

  int divide(int it, int *keeper)
{
  int divider, i;
  for (divider=1; divider <= it; divider++)
  {
  if (!(it % divider))// this was suggested by leiavoia.

  keeper[i] = (it/divider);
  cout << (it/divider) << " ";
  i++;
  }
  cout << "\n";
//  cout << "Press ENTER to continue..." << endl;

//  getchar ();

  return keeper;
}
The problem is, when I run it, windows generates an error and stops running it. Is this a problem with my code, my compiler (Dev-C++) or the OS itself? (I'm using Windows 2000) Thanks! ~Dakar [edited by - Dakar on May 7, 2004 4:11:50 PM]

Share this post


Link to post
Share on other sites
Advertisement
quote:
Original post by nobodynews
It doesn''t look like you are allocating any memory for keeper. Ie, you are writing on a part of memory you shouldn''t, and Windows "ain''t down wit dat" if you know what I mean.

You should probably use std::vector to store the numbers, it looks much more appropriate in this instance, unless you are trying to learn how to use pointers of course.


Well, I''m still a Newbie to programming, and this program is mainly to learn pointers.

Thanks.
~Dakar

Share this post


Link to post
Share on other sites
also you only really have to check the numbers between 1 and divident/2, (because dividing by more than divident/2 will result in a number lower than 2, which obviously wont be a natural number unless it is 1) might help efficiency if you are searching for factors of large numbers. just a thought

Share this post


Link to post
Share on other sites
I've done some improvements (such as making the for loop (it/2), and allocating memory for keeper) and now it works, under one condition: I enter a prime number. Then it writes "5570636". nothing else works. Am I doing something wrong, or should I switch compilers?

EDIT: new code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

int *divide(int it, int *keeper);

int main() //makes a divider program

{
int divident;
int *list;
int *listo;
cout << "This program divides a number by several others and shows the results.\n What shall the number be?";
cin >> divident;
cout << "\n";
divide(divident, list);
cout << list[1];
system("PAUSE");
return 0;
}

int *divide(int it, int *keeper)
{
keeper = new int;
int divider;
int i;
int total;
for (divider = 2; divider <= (it/2); divider++)
{
if (!(it % divider))// this was suggested by leiavoia

{
total = (it / divider);
keeper[i] = total;
cout << total << " ";
i++;
}
}
cout << "\n";
// cout << "Press ENTER to continue..." << endl;

// getchar ();

return keeper;
}


Also, I've commented out a couple of lines and it runs quite well if ( keeper = total; ) and ( cout << list[1]; ), so the problem is probably there.

Thanks!
~Dakar

[edited by - Dakar on May 7, 2004 7:21:44 PM]


[edited by - Dakar on May 7, 2004 7:29:42 PM]

Share this post


Link to post
Share on other sites
If it is a prime number then it hasn't dividers right? So in this case what the function is returning is in reality the pointer you gives it (i.e. the address)...

At least that is what I think... You know I'm also pretty new with C++ (altough I've been programming in VB for a while)

Also... try declaring "i" initializing it to zero, this may be a problem too...

Another thing, 512 works fine, but if you put 1024 it crashes, don't know why, sorry...

[edited by - VBBR on May 7, 2004 7:39:55 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by VBBR
If it is a prime number then it hasn''t dividers right? So in this case what the function is returning is in reality the pointer you gives it (i.e. the address)...

At least that is what I think... You know I''m also pretty new with C++ (altough I''ve been programming in VB for a while)


Well,( cout << list ) apparently displays the address of list.

I think the problem has to do with using keeper as an array. If I remove the brackets it will run.

Share this post


Link to post
Share on other sites
1) A pointer needs to point at something. If you're going to use it as an array, then you probably want to allocate an array of things that it points at instead of just a single thing. Think: How many times does your loop execute? Therefore, how many spots will you need in the array?

2) Assigning to an input parameter (in a useful way) requires pass-by-reference. Otherwise you're just reusing the name. Noone outside the function sees any change made to a pass-by-value parameter. Of course, an easier fix is to just allocate the memory outside the function - put your new[] statement in main() *before* you call the function.

OR, you could define the function so that it *returns* a new int[] containing the division results, and delete[] it in main() after you're done with the values. This way of doing things is a lot more friendly to the Java idiom though (since in Java there is no real equivalent to delete/delete[], the system is periodically scanning for unreachable bits of memory and freeing them up for you).

[edited by - Zahlman on May 7, 2004 10:25:34 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Zahlman
1) A pointer needs to point at something. If you''re going to use it as an array, then you probably want to allocate an array of things that it points at instead of just a single thing. Think: How many times does your loop execute? Therefore, how many spots will you need in the array?


The thing is, the only way to know how many spots are needed is to know all of the factors (minus itself and one) that are in the number.

quote:
2) Assigning to an input parameter (in a useful way) requires pass-by-reference. Otherwise you''re just reusing the name. Noone outside the function sees any change made to a pass-by-value parameter. Of course, an easier fix is to just allocate the memory outside the function - put your new[] statement in main() *before* you call the function.

OR, you could define the function so that it *returns* a new int[] containing the division results, and delete[] it in main() after you''re done with the values. This way of doing things is a lot more friendly to the Java idiom though (since in Java there is no real equivalent to delete/delete[], the system is periodically scanning for unreachable bits of memory and freeing them up for you).

[edited by - Zahlman on May 7, 2004 10:25:34 PM]


Sorry, but I don''t understand the last two paragaraphs. I''ll try to figure it out.

Anyway, I''ve fixed the problem. Apparently, I did not assign 0 to i, which made the compiler go on fritz. It now works.

Thanks anyway,
~Dakar.

Share this post


Link to post
Share on other sites
quote:
Original post by Dakar
quote:
Original post by Zahlman
1) A pointer needs to point at something. If you're going to use it as an array, then you probably want to allocate an array of things that it points at instead of just a single thing. Think: How many times does your loop execute? Therefore, how many spots will you need in the array?


The thing is, the only way to know how many spots are needed is to know all of the factors (minus itself and one) that are in the number.



Sure, but you can put an upper bound on it, at least.
Or if that's unacceptable, consider std::vector.

And yeah. Just as a general rule:


void foo(int input) {
...
input = /* STOP! Chances are you are writing a bug. The function that calls foo()
doesn't see the change to the value. */



In My Ideal Programming Language(TM), it is easy to use parameters as "out" parameters, but difficult to mess up. The best idea I've come up for that is a combination of Java-like object semantics, auto-boxing (or maybe just do things the Smalltalk way? I assume it treats objects similarly to how Java does WRT pointer/reference semantics?) and an explicit prohibition against assigning to the input variables. So:

function foo(Integer param) : int
Integer tmp = something;
tmp = somethingElse; // ok

param = somethingElse; // not allowed omg!!!11

param._ = 42; // ok, assigning to the value field. I think I like C++ style "const correctness" better than the idiom of making objects immutable

foo = param._; // this is one thing that Pascal etc. did very nicely IMHO - maybe it's just my style, but I tend to end up with a lot of variables named "result" whose purpose in life is to be returned...

return;



[Edit: Broadsheet == bad. Very bad.]

[edited by - Oluseyi on May 9, 2004 2:28:44 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Zahlman
And yeah. Just as a general rule:


void foo(int input) {
...
input = /* STOP! Chances are you are writing a bug. The function that calls foo()
doesn't see the change to the value. */




[edited by - Oluseyi on May 9, 2004 2:28:44 AM]


I think I see what you mean. Since it is a pass by value, main() won't see the change to input. But wouldn't it work if the return value Was input? It would also probably work if it was a pass by reference.

Just trying to clarify what I've read...

Thanks!
~Dakar

Edit: I've finished the code (using arrays instead of pointers), and another problem has cropped up: whenever I run it, it displays random numbers at the end instead of the common factors. Can anybody help?

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

int *divide(int it, int keeper[]);
int real(int fac[], int fac2[]);

int main() //makes a divider program

{
int divident, divident2;
cout << "This program divides a number by several others and shows the results.\n What shall the number be?";
cin >> divident;
int list[divident];
cout << "\n";
divide(divident, list);
cout << "\n\n" << "Now enter a larger number.\n";
cin >> divident2;
int listo[divident2];
cout << endl;
divide(divident2, list);
real(listo, list);
system("PAUSE");
return 0;
}

int *divide(int it, int keeper[])
{
int divider, total;
int i = 0;
keeper[i] = it;
i++;
for (divider = 2; divider<=(it / 2); divider++)
{
if (!(it % divider))// this was suggested by leiavoia

{
total = (it / divider);
keeper[i] = total;
cout << total << " ";
i++;
}
}
keeper[i] = 1;
cout << "\n";
return keeper;
}

int real(int fac[], int fac2[])
{
int r, s;
cout << "common factors are:";
for (r = 0; fac[r]; r++)
{
for (s = 0; fac2[s]; s++)
{
if (fac2[s] == fac2[r])
{
cout << fac[r] << " ";
}
}
}
cout << "\n";
return 0;
}



[edited by - Dakar on May 9, 2004 11:22:45 AM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!