I’m learning functions/pointers, and having a bit of an issue. What I need to write is a C program with main() and two other functions.
Requirements:
read_funct() must allocate enough memory using malloc() to store the data.
Function prototype for read_funct must be:
int read_funct(int *data_num, double **data_vals, char *filename)
How it’s meant to work:
main() calls the first function: read_funct()
read_num() reads binary data from a file. Two values have to be extracted: the no. of values (first 4 bytes), then the values themselves (8 bytes each, so contained in the next 8*no. of values). These correspond to data_num and data_vals. They have to be printed, the program then returns to main().
main() performs operations to edit the data from the first file.
main() calls the second function: write_funct(), which writes the edited data into a new file.
Where I am:
The first function reads data_num correctly, and reads/prints data_vals. This is all working properly. However, I’m trying to print these in main() to verify that I’m performing operations on the correct data, but I can’t get it working.
Note: I’m not trying to get it working with write_funct() at the moment, just taking it step-by-step.
Here’s my current code for main():
int read_funct(int *data_num, double **data_vals, char *filename);
int main()
{
int data_num;
double **data_vals;
//Reads file using read_funct()
read_funct(&data_num, data_vals, filename);
//Check: print data_num
printf("\nCheck No. of Values: %d\n", data_num);
//Check: print data_vals
for(int i = 0; i<data_num; i++)
{
printf("%0.3lf\t", data_vals[i]);
}
return(0);
}
Here’s read_funct()
int read_funct (int *data_num, double **data_vals, char *filename)
{
FILE * fp = fopen(filename, "rb"); //Opening file
//There's code here to check valid file open
//There's code here to determine size and check valid length
//Proceed with reading data_num if file is large enough
char buffer_n[4];
fread(buffer_n, 4, 1, fp);
int res = buffer_n[0]|(buffer_n[1] << 8)|(buffer_n[2] << 16)|(buffer_n[3] << 24); //Convert endian
data_num = &res; //Passes results back to data_num
printf("Number of Data Values: %d \n", *data_num); //Printing results
//Proceeds with calculating data_vals
data_vals = malloc(8*res); //Allocating memory
fread(data_vals, 8, res, fp);
//Prints data_vals
for(int i=0; i<res; i++)
{
printf("%0.3f\t", data_vals[i]);
}
printf("\nEnd of File Read.\n\n");
fclose(fp);
free(data_vals); //Free allocated memory
return(0);
}
Desired output:
Basically, I want it to print out the values from inside read_file() and then print a check in main(), so the output will be something like:
No. of values: 3 //From printf in read_file()
2 4 6
Check No. of values: 3 //From printf in main()
2 4 6
Where I think I'm going wrong:
Fairly sure that the main issue is that I've messed up my pointers and how I've initialised things in main(). I've been trying to fix this by myself, but I think I need some more experienced help to figure this out.
I know that every malloc() call must have a subsequent free(), but I'm worried that by doing so the way that I have, maybe I've made it so that I can't retrieve it in main(). Does it instead need to have an intermediate buffer to which memory is allocated instead?
Help to get this code working would be very greatly appreciated. Thank you!
Apart from freeing the data too soon, you have another problem here:
double **data_vals;
read_funct(&data_num, data_vals, filename);
If you want data_vals to be filled (written to, modified) by a function, you must pass its address, exactly as you do with data_num.
Here is another, slightly different, explanation. You see, you declare data_vals but you don't assign a value to it - it contains garbage. So it is a non-sense to pass data_vals to any function, or use it in any expression. It has a sense instead, to assign something to it, either via direct assignment or passing its address to a function, for the function to fill the variable.
Then, your usage of data_vals depicts a vector, or an array. So you really need to declare an array with [], or may be a pointer (pointers and arrays are quite related/interchangeable in C). The logic of your main() function requires a pointer, not a pointer to pointer. Hence, this is appropriate:
double *data_vals;
The function which writes to your pointer variable, instead, needs the address of the variable to write to; in other words: a pointer to a pointer. This is why your function has this (correct) signature:
read_funct(..., double **data_vals, ...)
To understand easily, let see the other (simpler) thing you wrote correctly:
int data_num;
read_funct(&data_num, ...); // declaration: read_funct(int *data_num, ...)
You declare data_num as integer in main(); you declare read_funct() with a formal parameter of pointer to integer, then you call read_funct() passing the address of your variable data_num. Perfect. Now, do the same with the other variable, data_vals. You declare it as pointer to double, pass its address to read_funct() using the notation &data_vals, and your function read_funct() declares that parameter as a pointer to pointer to double (and writes to it using *data_vals = .... You can see the parallelism between the two variables, right?
May be I've been too pedantic, but your question was really clear and well formed, so I tried to do the same.
Yes, you are free-ing the buffer too soon. After you have freed it, there is not guarantee as to what it contains. You can free it at the end, in main.
Related
I fairly new to C Programming, but fprintf() & printf() is behaving strangely and I'm so confused on why--I need some help understanding and diagnosing this issue.
fprintf() Deleting Element of Array
First off, I'm passing in a populated malloc allocated four element char** array into a simple function that will write to a file, everything in the array appears normal and all four elements contain the correct data. The function call in main() looks like this. My array in question is header.
Note: I had to cast this normal (char** array) as a constant in this function parameter, due to the function header parameter. Our professor gave us the header file and we cannot change anything in them.
pgmWrite((const char**) header, (const int**) matrix,
rowPixels, colPixels, outFile);
Next, stopping debugger just before it executes the fprintf() & printf() functions, screenshot showing the array is still populated with my 4 elements.
pgmWrite() - Showing array is still fine
Observe the 4th element of the array after execution of fprintf().
After fprintf() executes, element 3 memory is wiped out.
When run, printf() executes the printing of the array exactly what is shown in the debugger, ending at the 3rd element. Often printing nothing in that spot or in rare cases garbage characters. The behavior of printf() is exactly the same as how fprintf() is working as well.
I'm at a loss here guys, please help me understand what I'm doing wrong. I can only provide these two screenshots, based on me being a new member. I'll try to provide as much information as possible. Thank you. Here is a simplified version of my program. Keep in mind, the professor gave us the function declarations and told us we cannot change them. So, I have to work with what I have here. Also, since this is fileIO, you need to find a *.pgm file to test this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define rowsInHeader 4
#define maxSizeHeadRow 200
int ** pgmRead( char **header, int *numRows, int *numCols, FILE *in ){
// INITIALIZING
char *headArr[rowsInHeader][maxSizeHeadRow];
char buffer[100];
int r = 0;
fpos_t pos;
// CREATE: Header
while (r < 4){
// IF: Row in pgm file header lists the dimensions of matrix
if (r == 2){
// CURSOR: Saving pointer location in file (see notes in header for method reference)
fgetpos(in, &pos);
// ASSIGN: Dereference column and row pointers from file
fscanf(in, "%d %d", numCols, numRows);
// CURSOR: Moving back to saved pointer location (see notes in header for method reference)
fsetpos(in, &pos);
}
// ASSIGN: Copying header row into array
fgets(buffer, maxSizeHeadRow, in);
strcpy((char*)headArr[r], buffer);
// POINTER: Reference pointer to headArr[]
header[r] = (char*)headArr[r];
// TRAVERSE: To next row in file
r++;
}
// NOTE: Placeholder for return type
return 0;
}
int pgmWrite( const char **header, const int **pixels, int numRows, int numCols, FILE *out ){
// INITIALIZING
int i = 0;
// WRITE: Header
for (i = 0; i < rowsInHeader; i++){
fprintf(out, "%s", header[i]);
printf("%s", header[i]);
}
return 0;
}
int main(int argc, char *argv[]){
char **header = (char**)malloc(rowsInHeader * sizeof(char));
FILE *inFile = fopen("smallFile.pgm", "r");
FILE *outFile = fopen("TestPicture.ascii.pgm", "w");;
int rowPixels = 0;
int colPixels = 0;
int **matrix = NULL;
// READ & WRITE
matrix = pgmRead(header, &rowPixels, &colPixels, inFile);
pgmWrite((const char**)header, (const int**)matrix, rowPixels, colPixels, outFile);
// FINALIZING
fclose(inFile);
free(header);
return 0;
}
You are not allocating your array correctly. This line:
char **header = (char**)malloc(rowsInHeader * sizeof(char));
makes header point to an uninitialized region of memory , size 4 bytes.
Then inside your PGM function you write:
header[r] = (char*)headArr[r];
The code header[r] means to access the r'th pointer stored in the space pointed to by headArr. But since that space is only 4 bytes big, you're actually writing off into the wild blue yonder.
Also, (char *)headArr[r] is a mistake. If you did not use the cast, your compiler would have warned you about this mistake. You should avoid using casts in your code, especially using them to make warnings go away. You're saying to the compiler "Ssh, I know what I'm doing" when in fact you don't know what you are doing.
The entire approach with headArr is flawed from the start: even if you had actually written the right code to implement what you were trying, you'd be returning pointers into space which is deallocated when the function returns.
Basically the whole pgmRead function is a complete mess and it'd be easier to start from scratch. But this time, think carefully about when and where you are allocating memory, and what the types are of your expressions, and don't use casts. Let the pgmRead function do all the allocation.
(Unfortunately, based on your description it looks like you will have to use your casts to call the pgmWrite function since that has a mistake in its signature. const int ** should be const int * const *, and similarly for const char **. I'd recommend to actually change pgmWrite's signature accordingly, get your program working, and then once everything is good, then go back to the broken version that you are forced to use.)
Reading C FAQ - arrays and pointers might be useful too.
Before you feel the need to mark this as a duplicate post, please don't. I have read all the threads on pointers, arrays, and functions I could find but almost all of them are far too advanced to be of any help to me.
I'm not getting an error, however my code will not print my array. It seems the issue here is using scanf. I don't think the values entered are actually being put into the array in main(). I've tried using pointers, but then I get the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" whenever I try to use scanf to collect user inputted values to put into the array.
What I am working on is limited to declaring my array in the main() function, but all the operations are to be performed in promptData() function. Any help would be great, I'm at my wits end trying to figure this out on my own.
#import <stdio.h>
void promptData(double data[], int numElem);
int main(int argc, const char * argv[])
{
int size, i;
double array[size];
promptData(array, size);
for (i = 0; i < size; i++)
printf("%.2lf\n", array[i]);
return 0;
}
void promptData(double data[], int numElem)
{
int i;
printf("Enter integer values for size of array.\n");
scanf("%i", &numElem);
for (i = 0; i < numElem; i++)
{
printf("Enter array values.\n");
scanf("%lf", &data[i]);
}
}
Your program has undefined behaviour because variable size was not initialized and has indeterminate value.
You should at first in main ask the user to enter the size of the array then define the array itself and only after that fill it with values.
For example
int main(int argc, const char * argv[])
{
int size = 0;
printf( "Enter a positive integer value for the size of the array: ");
scanf( "%i", &size);
if ( size == 0 ) exit( 1 );
double array[size];
promptData(array, size);
//...
Also in C there is no such a directive as
#import <stdio.h>
Use instead
#include <stdio.h>
At least in ANSI C 89 and C 90, you can't give a variable as the size of an array. The size of array should be known at compile time. You should be doing something like double array[size];.
Even in C99, where you can have variable sized arrays; the variables should contain proper index values at the time you declare the array. In that case, you should read the number from stdin and then declare the array.
Also in C, all parameters are passed by value. This means every function takes a copy of the parameters in the function. If you want to modify a variable's value, you should pass a pointer to it, and then modify the pointer's dereferenced value, something like:
void change(int *x)
{
*x = 7;
}
void first(void)
{
int x = 5;
change(&x);
printf("%d\n", x);
}
Adding on to the other, correct, answer by Zenith, if you want a dynamically allocated array (like you want to be able to change its size based on user input), then your only option is to use one of the memory allocation functions like malloc().
Once you actually have the size in your main function, declare your array like this:
int *myArray = malloc(sizeof(int) * size));//note that malloc will return a NULL if it fails
//you should always check
if(myArray != null) {
//do stuff with myArray like you were. You can just use myArray[] as long as you
//make SURE that you don't go beyond 'size'
}
free(myArray);
//VERY important that every malloc() has a free() with it
Note: untested, but the idea is there.
Further, to answer your other question.
If you find yourself in a situation where you need to call a function and use things INSIDE that function to change stuff where you called it, you have only two choices in C.
You can either return the value and assign it to a variable in the calling function like this:
int result = myFunction(someVariable, anotherVariable);
//do stuff with result
Or, use pointers.
I'm not explaining pointers here, that's usually several lectures worth of information, and is one of the more difficult concepts to grasp for introductory programmers. All I can tell you is you need to learn them, but this format is not the right way to go about doing that.
You're passing size to promptData as a copy.
Thus changes to numElem inside promptData will not affect the size variable in your main. Hence size remains uninitialized, i.e. has an undefined value and therefore should not be used as a size for an array.
If you need to initialize an array with a size that's only known at run-time, you need to allocate memory for the array dynamically using malloc, for example:
double* array = malloc(size * sizeof(double));
First, I declare variables before the main() function:
// Files
FILE *density_model_file;
char *density_model_filename;
float *density_array;
Next, I open the FILE * for reading and allocate memory for the density array:
density_model_file = open4read(density_model_filename, program_name);
density_array = allocator(density_model_size, sizeof(float));
Up to this point, the debugger shows everything is working fine. Here
is the step that I can't seem to fix, where I am attempting to load
data into the calloc'd array:
density_array = floatfromfile(sizeof(float), density_model_size, density_model_file, density_model_filename);
The density_array has a NULL value after this step for some reason.
Here is the code for this function (contained in a separate .c file).
I have bolded the part where I think the issue exists:
float * floatfromfile(unsigned long int entrysize, int numentries, FILE *inputfile, const char *filename)
{
/* Declaration of density model array size variable */
int numbytes;
**void *temparray = 0;
/* Writes the gravity model to file */
numbytes = (int)fread(temparray, entrysize, numentries, inputfile);**
/* Checks that the forward model file has a sufficient number of entries */
if (numbytes == numentries)
{
printf("loaded %i values from %s using fread()\n", numbytes, filename);
return((float *)temparray);
}
else
{
printf("ERROR: %i data points read from %s of %i needed\n", numbytes, filename, numentries);
return((float *)temparray);
}
}
Any insight would be much appreciated. I think the issue might be that calloc() returns a pointer to a void array. I can provide the other functions if needed.
You seem to have a misunderstanding about how pointers work. What you need to do is pass density_array into floatfromfile as an argument.
What you are doing instead is overwriting the pointer to your allocated memory, with the return value from floatfromfile. That return value is always NULL because that's what you assigned it to (as temparray).
fread expects to be able to write its results into an allocated memory block. But you're giving it temparray which has not been allocated—in fact its value is 0. So you're giving fread the address 0 to write into, which is likely to cause the program to crash. Instead you need to pass your allocated pointer density_array at this point.
Since I'm very new to C programming, I have a probably very simple problem.
I got a struct looking like this
typedef struct Vector{
int a;
int b;
int c;
}Vector;
Now I want to write an array of Vectors in a file. To achieve that, I thought to create following method scheme
String createVectorString(Vector vec){
// (1)
}
String createVectorArrayString(Vector arr[]){
int i;
String arrayString;
for(i=0; i<sizeof(arr); i++){
//append createVectorString(arr[i]) to arrayString (2)
}
}
void writeInFile(Vector arr[]){
FILE *file;
file = fopen("sorted_vectors.txt", "a+");
fprintf(file, "%s", createVectorArrayString(arr);
fclose(file);
}
int main(void){
// create here my array of Vectors (this has already been made and is not part of the question)
// then call writeInFile
return 0;
}
My main problems are at (1), which involves also (2) (since I have no clue how to work with Strings in C, eclipse is saying "Type "String" unknown", although I included <string.h>)
So I read at some point that transforming an int to a String is possible with the method itoa().
As I understood it, I can simply do following
char buf[33];
int a = 5;
itoa(a, buf, 10)
However, I cannot bring that to work, let alone that I can't figure out how to "paste" chars or ints into a String.
In my point (1), I would like to create a String of the Form (a,b,c), where as a, b and c are the "fields" of my struct Vector.
In point (2), I would like to create a single String of the Form (a1,b1,c1)\n(a2,b2,c2)\n...(an,bn,cn), whereby n is the amount of Vectors in the array.
Is there a quick solution? Do I confuse the concept of Strings from Java with them of C?
Yes, you do confuse the concept of strings in Java and C.
The C strings are rather inconvenient to work with. They require dynamic memory allocation, and what is worse, corresponding deallocation (which is possible but tedious). In your case, it might be best to remove strings completely, and implement whatever you need without strings.
To write a vector directly to file:
Vector vec;
FILE* file = ...;
fprintf(file, "%d %d %\n", vec.a, vec.b, vec.c);
To write an array of vectors, just do the above in a loop.
A string, in C, is just a null-terminated array of characters. It is generally declared as a char *, though if you have a fixed maximum length, and can allocate it on the stack or inline in a structure, it might be declared as char str[LENGTH].
One of the easiest ways to build a string out of a mix of characters and numbers is to use snprintf(). This is like printf(), but instead of printing to standard output, will print into a string (an array of char). Note that you need to allocate and pass in the buffer yourself; so you will either need to know the maximum length beforehand, or find out by trying to call snprintf(), finding out how many characters it would print, allocating an array of that size, and calling snprintf() again to actually print the result.
So if you have a vector of three integers, and want to build a string out of it, you could write:
char *createVectorString(Vector vec){
int count = snprintf(NULL, 0, "(%d,%d,%d)", vec.a, vec.b, vec.c);
if (count < 0)
return NULL;
char *result = malloc(count * sizeof(char));
if (result == NULL)
return NULL;
count = snprintf(result, count, "(%d,%d,%d)", vec.a, vec.b, vec.c);
if (count < 0)
return NULL;
return result;
}
Note that because you called malloc() to allocate this buffer, you will need to call free() once you are done with it, to avoid a memory leak.
Note that snprintf() only returns the length that you need as of C99. Some compilers (like MSVC), don't support C99 yet, so they return -1 instead of the length that the string would be. In those cases, there may be another function that you can call to determine the size of buffer you need (in MSVC, it's _vscprintf), or you may need to just guess at a size, and if that doesn't work, allocate a buffer twice that size and try again, until it succeeds.
In short: yes, you are confusing Java Strings with C, where you do not have standard string type. What is a string is in reality a sequence of chars terminated with a char with value 0 (or '\0', if you want to be purist).
The quickest solution is to not generate strings (and manually allocate all the memory), but rather to use fprintf with FILE*. Instead of functions to create strings, write functions to write various things into supplied FILE*, for example int writeVector(FILE* output, Vector v). It will be easier for the beginning. I don't think all the gory details of manual memory management required for constructing such strings are good start.
(Note the return type of int in proposed prototype; this is for error codes.)
Additionally, as one of the commenters noted, you misunderstand sizeof. sizeof(arr) would return size of all the elements of the array combined, in bytes (well, technically in chars, but it's a distinction you don't need to worry about right now). To get number of elements in an array, you'd need to use sizeof(arr)/sizeof(arr[0]). But I'm not sure it would work with your function argument, which is technically a pointer, despite the fancy syntax. Applying sizeof to pointer will return size of the pointer itself, not the data it points to.
Which is why in C you would usually provide size of an array in an extra function argument, like:
String createVectorArrayString(Vector arr[], size_t n)
or more in line with what I wrote above:
int writeVectorArray(FILE *output, Vector arr[], size_t n)
{
int retcode = 0;
size_t i;
for (i = 0; i < n; ++i) {
if ( (retcode = writeVector(output, arr[i])) != 0)
return retcode;
}
}
Yes, you are confusing Java Strings with C.
you can't pass arrays in C, only pointers to the first element.
sizeof (arr) where arr is a function argument is the size of the pointer.
You can't return a block scope String, only a pointer to a string. But pointers to local automatic variables go out of scope when the function returns.
I'd write a loop more along
#define N 42
/* Typedef for Vector assumed somewhere.*/
Vector arr[N];
/* Fill arr[]. */
for (i = 0; i < N; ++i) {
fprintf (file, "arr[%d] = { a=%d, b=%d, c=%d }\n", i, arr[i].a, arr[i].b, arr[i].c);
}
I've just started learning C (coming from a C# background.) For my first program I decided to create a program to calculate factors. I need to pass a pointer in to a function and then update the corresponding variable.
I get the error 'Conflicting types for findFactors', I think that this is because I have not shown that I wish to pass a pointer as an argument when I declare the findFactors function. Any help would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
int *findFactors(int, int);
int main (int argc, const char * argv[])
{
int numToFind;
do {
printf("Enter a number to find the factors of: ");
scanf("%d", &numToFind);
} while (numToFind > 100);
int factorCount;
findFactors(numToFind, &factorCount);
return 0;
}
int *findFactors(int input, int *numberOfFactors)
{
int *results = malloc(input);
int count = 0;
for (int counter = 2; counter < input; counter++) {
if (input % counter == 0){
results[count] = counter;
count++;
printf("%d is factor number %d\n", counter, count);
}
}
return results;
}
Change the declaration to match the definition:
int *findFactors(int, int *);
I apologise for adding yet another answer but I don't think anyone has covered every point that needs to be covered in your question.
1) Whenever you use malloc() to dynamically allocate some memory, you must also free() it when you're done. The operating system will, usually, tidy up after you, but consider that you have a process during your executable that uses some memory. When said process is done, if you free() that memory your process has more memory available. It's about efficiency.
To use free correctly:
int* somememory = malloc(sizeyouwant * sizeof(int));
// do something
free(somememory);
Easy.
2) Whenever you use malloc, as others have noted, the actual allocation is in bytes so you must do malloc(numofelements*sizeof(type));. There is another, less widely used, function called calloc that looks like this calloc(num, sizeof(type)); which is possibly easier to understand. calloc also initialises your memory to zero.
3) You do not need to cast the return type of malloc. I know a lot of programming books suggest you do and C++ mandates that you must (but in C++ you should be using new/delete). See this question.
4) Your function signature was indeed incorrect - function signatures must match their functions.
5) On returning pointers from functions, it is something I discourage but it isn't wrong per se. Two points to mention: always keep 1) in mind. I asked exactly what the problem was and it basically comes down to keeping track of those free() calls. As a more advanced user, there's also the allocator type to worry about.
Another point here, consider this function:
int* badfunction()
{
int x = 42;
int *y = &x;
return y;
}
This is bad, bad, bad. What happens here is that we create and return a pointer to x which only exists as long as you are in badfunction. When you return, you have an address to a variable that no longer exists because x is typically created on the stack. You'll learn more about that over time; for now, just think that the variable doesn't exist beyond its function.
Note that int* y = malloc(... is a different case - that memory is created on the heap because of the malloc and therefore survives the end of said function.
What would I recommend as a function signature? I would actually go with shybovycha's function with a slight modification:
int findFactors(int* factors, const int N);
My changes are just personal preference. I use const so that I know something is part of the input of a function. It isn't strictly necessary with just an int, but if you're passing in pointers, remember the source memory can be modified unless you use const before it, whereon your compiler should warn you if you try to modify it. So its just habit in this case.
Second change is that I prefer output parameters on the left because I always think that way around, i.e. output = func(input).
Why can you modify function arguments when a pointer is used? Because you've passed a pointer to a variable. This is just a memory address - when we "dereference" it (access the value at that address) we can modify it. Technically speaking C is strictly pass by value. Pointers are themselves variables containing memory addresses and the contents of those variables are copied to your function. So a normal variable (say int) is just a copy of whatever you passed in. int* factors is a copy of the address in the pointer variable you pass in. By design, both the original and this copy point to the same memory, so when we dereference them we can edit that memory in both the caller and the original function.
I hope that clears a few things up.
EDIT: no reference in C (C++ feature)
Don't forget to modify numberOfFactors in the method (or remove this parameter if not useful). The signature at the beginning of your file must also match the signature of the implementation at the end (that's the error you receive).
Finally, your malloc for results is not correct. You need to do this:
int *results = malloc(input * sizeof(int));
int* ip <- pointer to a an int
int** ipp <- pointer to a pointer to an int.
int *findFactors(int, int); line says you wanna return pointer from this function (it's better to use asteriks closer to the type name: int* moo(); - this prevents misunderstandings i think).
If you wanna dynamically change function argument (which is better way than just return pointer), you should just use argument as if you have this variable already.
And the last your mistake: malloc(X) allocates X bytes, so if you want to allocate memory for some array, you should use malloc(N * sizeof(T));, where N is the size of your array and T is its type. E.g.: if you wanna have int *a, you should do this: int *a = (int*) malloc(10 * sizeof(int));.
And now here's your code, fixed (as for me):
#include <stdio.h>
#include <stdlib.h>
int findFactors(int, int*);
int main(int argc, char **argv)
{
int numToFind, *factors = 0, cnt = 0;
do
{
printf("Enter a number to find the factors of: ");
scanf("%d", &numToFind);
} while (numToFind > 100);
cnt = findFactors(numToFind, factors);
printf("%d has %d factors.\n", numToFind, cnt);
return 0;
}
int findFactors(int N, int* factors)
{
if (!factors)
factors = (int*) malloc(N * sizeof(int));
int count = 0;
for (int i = 2; i < N; i++)
{
if (N % i == 0)
{
factors[count++] = i;
printf("%d is factor number #%d\n", i, count);
}
}
return count;
}
Note: do not forget to initialize your pointers any time (as i did). If you do want to call function, passing a pointer as its argument, you must be sure it has value of 0 at least before function call. Otherwise you will get run-time error.