I want to pass a pointer to pointer to a function, allocate memory in function, fill it with strings and get it back, but all seems not to be working. Program prints nothing outside the function. There is most important pieces of code:
struct record ** getRegEx( int *counter, char** keys )
{
*counter = 0;
//get some records, its number is *counter, max lenght of each string is 64
//COUNTER IS NOT 0! ITS VALUE DEPENDS ON OTHER OPERATIONS I HAVENT WRTTEN HERE
//...
keys =(char ** ) malloc((*counter)*(sizeof(char *)));
for (j = 0; j < *counter; j++)
{
keys[j] = (char* )malloc(64*sizeof(char));
}
strcpy(keys[j],key.dptr);
printf("size %d : \n", sizeof(**keys));//1
printf("size %d : \n", sizeof(*keys));//4
printf("size %d : \n", sizeof(keys[0]));//4
printf("size %d : \n", sizeof(keys));//4
//...
}
/*Out of the function, inside the function OK*/
char** keys;
int count;
results = getRegEx(&count, &keys); //&keys or keys - makes no difference
for(int k=0 ; k< *count;k++) //test
{
printf("keys in db %s: s\n", keys[k]); //nothing!?
}
I have made it works by replacing function header with something like struct record ** getRegEx( int *counter, char*** keys ) (and using *keys and *keys[i] instead of key and keys[i] inside the function). Thanks for All!
You are passing zero to malloc so you have nothing to return in keys.
Your for loop never runs.
Both are because (*counter) is zero.
There's a serious problem here:
results = getRegEx(&count, &keys); //&keys or keys - makes no difference
Your comment is wrong - it does make a difference. keys is of type char ** (which getRegEx expects), &keys is of type char ***.
Your function has a return type, but returns nothing.
You allocate dynamic memory for your keys variable in the function, but the function (as it's written) cannot pass that memory out of the function. Your function should take a char ***, and you should pass it as &keys (which, as previously stated, is of type char ***.)
Your size is always going to be zero, since you set *count = 0 at the beginning of your function (when you shouldn't be setting it at all in your function, and should be passing count by value instead of by pointer). The exact effects of malloc(0) are implementation defined.
You cast the return value of malloc. This isn't wrong, but it's unnecessary in C (and if you're really using C++, you should say so) and can make things harder down the road.
You never check the return values of malloc for failure.
You use the counter pointer outside the function where it is declared. Outside the function call, you should be using the count variable you passed as a parameter. Function parameters don't continue to exist outside the functions they're used in.
Major issues:
Your types don't match up. In the call to getRegEx(&count, &keys), the type of the expression &keys is char ***, not char **. Note that if you want to modify the value of keys, you will have to pass a pointer to it. This leads to the next problem...
Because you're modifying the value of the parameter keys, not what it points to, any changes you make in the function are not reflected in the caller.
Here's a modified version of your code, illustrating what I think you're trying to do:
struct record **getRegEx(int *counter, char ***keys)
{
...
// type of keys = char ***
// type of *keys = char **
// type of **keys = char *
*keys = malloc(*counter * sizeof **keys); // note no cast, operand of sizeof
if (*keys)
{
int j;
for (j = 0; j < *counter; j++)
{
// type of (*keys)[j] == char *
// type of *(*keys)[j] = char
(*keys)[j] = malloc(64 * sizeof *(*keys)[j]);
}
}
...
}
Note that I don't cast the result of malloc. As of the 1989 version of the C standard, you don't have to, so it saves from visual clutter. It also protects you from a potential bug; if you forget to include stdlib.h or otherwise don't have to prototype for malloc in scope, the compiler will assume the function returns int. Without the cast, you'll get diagnostic on the order of "incompatible types for assignment." Adding the cast will supress the diagnostic, and you may have subtle (or not-so-subtle) runtime errors as a result.
Also, note that I'm using sizeof on objects, not types. Again, this helps reduce visual clutter, and it also protects you in case you decide to change the base type of keys; you don't have to update every malloc call as well.
Why (*keys)[j] instead of *keys[j]? The expression keys is not the location of the beginning of our array, but rather points to that location. We have to dereference keys to get the address of the array, which we then subscript.
You have a function getRegEx, that is declared to return a struct record **.
You know what's missing from that function?
anything that looks like a return statement!
Related
I've been trying for a while now and I can not seem to get this working:
char** fetch (char *lat, char*lon){
char emps[10][50];
//char** array = emps;
int cnt = -1;
while (row = mysql_fetch_row(result))
{
char emp_det[3][20];
char temp_emp[50] = "";
for (int i = 0; i < 4; i++){
strcpy(emp_det[i], row[i]);
}
if ( (strncmp(emp_det[1], lat, 7) == 0) && (strncmp(emp_det[2], lon, 8) == 0) ) {
cnt++;
for (int i = 0; i < 4; i++){
strcat(temp_emp, emp_det[i]);
if(i < 3) {
strcat(temp_emp, " ");
}
}
strcpy(emps[cnt], temp_emp);
}
}
}
mysql_free_result(result);
mysql_close(connection);
return array;
Yes, I know array = emps is commented out, but without it commented, it tells me that the pointer types are incompatible. This, in case I forgot to mention, is in a char** type function and I want it to return emps[10][50] or the next best thing. How can I go about doing that? Thank you!
An array expression of type T [N][M] does not decay to T ** - it decays to type T (*)[M] (pointer to M-element array).
Secondly, you're trying to return the address of an array that's local to the function; once the function exits, the emps array no longer exists, and any pointer to it becomes invalid.
You'd probably be better off passing the target array as a parameter to the function and have the function write to it, rather than creating a new array within the function and returning it. You could dynamically allocate the array, but then you're doing a memory management dance, and the best way to avoid problems with memory management is to avoid doing memory management.
So your function definition would look like
void fetch( char *lat, char *lon, char emps[][50], size_t rows ) { ... }
and your function call would look like
char my_emps[10][50];
...
fetch( &lat, &lon, my_emps, 10 );
What you're attempting won't work, even if you attempt to cast, because you'll be returning the address of a local variable. When the function returns, that variable goes out of scope and the memory it was using is no longer valid. Attempting to dereference that address will result in undefined behavior.
What you need is to use dynamic memory allocation to create the data structure you want to return:
char **emps;
emps = malloc(10 * sizeof(char *));
for (int i=0; i<10; i++) {
emps[i] = malloc(50);
}
....
return emps;
The calling function will need to free the memory created by this function. It also needs to know how many allocations were done so it knows how many times to call free.
If you found a way to cast char emps[10][50]; into a char * or char **
you wouldn't be able to properly map the data (dimensions, etc). multi-dimensional char arrays are not char **. They're just contiguous memory with index calculation. Better fit to a char * BTW
but the biggest problem would be that emps would go out of scope, and the auto memory would be reallocated to some other variable, destroying the data.
There's a way to do it, though, if your dimensions are really fixed:
You can create a function that takes a char[10][50] as an in/out parameter (you cannot return an array, not allowed by the compiler, you could return a struct containing an array, but that wouldn't be efficient)
Example:
void myfunc(char emp[10][50])
{
emp[4][5] = 'a'; // update emp in the function
}
int main()
{
char x[10][50];
myfunc(x);
// ...
}
The main program is responsible of the memory of x which is passed as modifiable to myfunc routine: it is safe and fast (no memory copy)
Good practice: define a type like this typedef char matrix10_50[10][50]; it makes declarations more logical.
The main drawback here is that dimensions are fixed. If you want to use myfunc for another dimension set, you have to copy/paste it or use macros to define both (like a poor man's template).
EDITa fine comment suggests that some compilers support variable array size.
So you could pass dimensions alongside your unconstrained array:
void myfunc(int rows, int cols, char emp[rows][cols])
Tested, works with gcc 4.9 (probably on earlier versions too) only on C code, not C++ and not in .cpp files containing plain C (but still beats cumbersome malloc/free calls)
In order to understand why you can't do that, you need to understand how matrices work in C.
A matrix, let's say your char emps[10][50] is a continuous block of storage capable of storing 10*50=500 chars (imagine an array of 500 elements). When you access emps[i][j], it accesses the element at index 50*i + j in that "array" (pick a piece of paper and a pen to understand why). The problem is that the 50 in that formula is the number of columns in the matrix, which is known at the compile time from the data type itself. When you have a char** the compiler has no way of knowing how to access a random element in the matrix.
A way of building the matrix such that it is a char** is to create an array of pointers to char and then allocate each of those pointers:
char **emps = malloc(10 * sizeof(char*)); // create an array of 10 pointers to char
for (int i = 0; i < 10; i++)
emps[i] = malloc(50 * sizeof(char)); // create 10 arrays of 50 chars each
The point is, you can't convert a matrix to a double pointer in a similar way you convert an array to a pointer.
Another problem: Returning a 2D matrix as 'char**' is only meaningful if the matrix is implemented using an array of pointers, each pointer pointing to an array of characters. As explained previously, a 2D matrix in C is just a flat array of characters. The most you can return is a pointer to the [0][0] entry, a 'char*'. There's a mismatch in the number of indirections.
Hello i am trying to write a function which return the number of elements of the array passed as parameter, the function have to work on an array of any type.
I tried this:
int nb_elems(void* array)
{
void* end = array;
while(*end != NULL) // The last element have to be null, it is not counted.
end++;
return end - array;
}
As you can guess, it doesn't work.
In fact it doesn't even compile, i get these errors:
Error: Illegal indirection. < while(*end != NULL) >
Error: void * : size unknown. < while(*end != NULL) >
Error: void * : size unknown. < return end - array >
First, could you tell me if what i am trying to do is possible?
Second, is the way i am trying to achieve this makes sense, or am i completely missing the point?
Then, why do i get these errors, what does they means?
Thanks for your help!
As C does not pass arrays, nb_elems(void* array) received a pointer. The void *pointer does not know how many elements (nor the type) which its points to.
Since it needs to "work on an array of any type", code needs to define how to compare an arbitrary type with NULL.
To your function, you need to pass the pointer, the size of an array element and a function to use to test against NULL.
int nb_elems(void* array, size_t esize, int (*cmp)(void *ptr)) {
char *ptr = array;
int count = 0;
while (*cmp(ptr) == 0) {
ptr += esize;
count++;
}
return count;
}
because you are checking != NULL i suppose you have an array of pointers. with array of pointer your code could work because you know the size of pointers even if it is a void pointer.
if my assumptions were right you could code it like this:
int nb_elems(void** array) {
void** end = array;
while(*end != NULL) {
end++;
}
return end - array;
}
but this code only works with pointer to pointer or array of pointer.
usage:
int** iptrs = (int**)malloc(3 * sizeof(int*));
iptrs[0] = (int*)malloc(sizeof(int));
*(iptrs[0]) = 42;
iptrs[1] = (int*)malloc(sizeof(int));
*(iptrs[1]) = 23;
iptrs[2] = NULL;
printf("%d", nb_elems(iptrs));
the example prints 2
No, the way your are doing it is not possible, because to do pointer arithmetic (here the ++ and the -) the compiler has to know the size of the base type of the array.
Also void* is a pointer to void, that is to a "non-type". So *end has type void and you can't compare it to anything, in particular not to NULL, which could be a pointer type or an integer. Just use 0 if you compare a base type for being zero.
Before starting to even try to do this for pointers of any type, you should try the same for pointers to a known type, say unsigned or double. If you change your code with that in mind, it has good chances to work.
The reason your code doesn't compile, is because of the fact that the compiler cannot determine the size of a void. Take for example the ++ operator. We could roughly translate this to:
end = end + sizeof(void);
The size of a void is not defined, so the compiler cannot generate any code for this, giving you one error.
Next you try to dereference a void pointer. This would give you something with the type void. But since a void does not represent anything (it represents nothing), the compiler cannot tell what this should be. You then use the equality operator to compare nothing to NULL. You cannot compare nothing to something, so this will generate an error.
In C, it is impossible to implement a function that would do something like this, simply because of the fact that you cannot tell what the type of the void* will be. You at least need to know the type your passed to your function and what type-specific value will be used to terminate the array. C does not offer this functionality, making the implementation of such a function impossible.
If you have an actual array, not a pointer, you can use sizeof(array) / sizeof(array[0]) to determine the number of elements in it.
I'm in the process of teaching myself C and I'm mistified as to what's causing the following issue: when I create an array in a method and return it as a pointer to the calling function, none of the content is correct. I've boiled down this problem to the following example:
char * makeArr(void){
char stuff[4];
stuff[0]='a';
stuff[1]='b';
stuff[2]='c';
stuff[3]='d';
printf("location of stuff:%p\n",stuff);
int i;
for(i = 0; i < 4; i++){
printf("%c\n",stuff[i]);
}
return stuff;
}
int main(void){
char* myarr;
myarr = makeArr();
int i;
printf("\n");
printf("location of myarr:%p\n", myarr);
for(i = 0; i < 4; i++){
printf("%c\n",myarr[i]);
}
}
The output returns the following:
location of stuff:0028FF08
a
b
c
d
location of myarr:0028FF08
Ä
ÿ
(
(a null character)
So I've verified that the locations between the two values are the same, however the values differ. I imagine that I'm missing some critical C caveat; I could speculate it's something to do with an array decaying into a pointer or a problem with the variable's scope, but and any light that could be shed on this would be much appreciated.
What you're attempting to do is return the address of a local variable, one that goes out of scope when the function exits, no different to:
char *fn(void) {
char xyzzy = '7';
return &xyzzy;
}
That's because, other than certain limited situations, an array will decay into a pointer to the first element of that array.
While you can technically return that pointer (it's not invalid in and of itself), what you can't do is dereference it afterwards with something like:
char *plugh = fn();
putchar (*plugh);
To do so is undefined behaviour, as per C11 6.5.3.2 Address and indirection operators /4 (my bold):
If an invalid value has been assigned to the pointer, the behaviour of the unary * operator is undefined.
Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime.
Having stated the problem, there are (at least) two ways to fix it.
First, you can create the array outside of the function (expanding its scope), and pass its address into the function to be populated.
void makeArr (char *stuff) {
stuff[0]='a';
stuff[1]='b';
stuff[2]='c';
stuff[3]='d';
}
int main(void) {
char myarr[4];
makeArr (myarr);
// Use myarr here
}
Second, you can dynamically allocate the array inside the function and pass it back. Items created on the heap do not go out of scope when a function exits, but you should both ensure that the allocation succeeded before trying to use it, and that you free the memory when you're finished with it.
char *makeArr (void) {
char *stuff = malloc (4);
if (stuff != NULL) {
stuff[0]='a';
stuff[1]='b';
stuff[2]='c';
stuff[3]='d';
}
return stuff;
}
int main(void) {
char *myarr;
myarr = makeArr();
if (myarr != NULL) {
// Use myarr here
free (myarr);
}
}
stuff[] only exists on the stack during function call, it gets written over after return. If you want it to hold values declare it static and it will do what you want.
However, the whole idea is fundamentally lame, don't do that in real life. If you want a function to initialize arrays, declare an array outside of the function, pass a pointer to this array as a parameter to the function and then initialize an array via that pointer. You may also want to pass the size of the array as a second parameter.
Since you're learning, a sample code is omitted intentionally.
Your array stuff is defined locally to the function makeArr. You should not expect it to survive past the life of that function.
char * makeArr(void){
char stuff[4];
Instead, try this:
char * makeArr(void){
char *stuff=(char*)calloc(4, sizeof(char));
This dynamically creates an array which will survive until you free() it.
I am supposed to follow the following criteria:
Implement function answer4 (pointer parameter and n):
Prepare an array of student_record using malloc() of n items.
Duplicate the student record from the parameter to the array n
times.
Return the array.
And I came with the code below, but it's obviously not correct. What's the correct way to implement this?
student_record *answer4(student_record* p, unsigned int n)
{
int i;
student_record* q = malloc(sizeof(student_record)*n);
for(i = 0; i < n ; i++){
q[i] = p[i];
}
free(q);
return q;
};
p = malloc(sizeof(student_record)*n);
This is problematic: you're overwriting the p input argument, so you can't reference the data you were handed after that line.
Which means that your inner loop reads initialized data.
This:
return a;
is problematic too - it would return a pointer to a local variable, and that's not good - that pointer becomes invalid as soon as the function returns.
What you need is something like:
student_record* ret = malloc(...);
for (int i=...) {
// copy p[i] to ret[i]
}
return ret;
1) You reassigned p, the array you were suppose to copy, by calling malloc().
2) You can't return the address of a local stack variable (a). Change a to a pointer, malloc it to the size of p, and copy p into. Malloc'd memory is heap memory, and so you can return such an address.
a[] is a local automatic array. Once you return from the function, it is erased from memory, so the calling function can't use the array you returned.
What you probably wanted to do is to malloc a new array (ie, not p), into which you should assign the duplicates and return its values w/o freeing the malloced memory.
Try to use better names, it might help in avoiding the obvious mix-up errors you have in your code.
For instance, start the function with:
student_record * answer4(const student_record *template, size_t n)
{
...
}
It also makes the code clearer. Note that I added const to make it clearer that the first argument is input-only, and made the type of the second one size_t which is good when dealing with "counts" and sizes of things.
The code in this question is evolving quite quickly but at the time of this answer it contains these two lines:
free(q);
return q;
This is guaranteed to be wrong - after the call to free its argument points to invalid memory and anything could happen subsequently upon using the value of q. i.e. you're returning an invalid pointer. Since you're returning q, don't free it yet! It becomes a "caller-owned" variable and it becomes the caller's responsibility to free it.
student_record* answer4(student_record* p, unsigned int n)
{
uint8_t *data, *pos;
size_t size = sizeof(student_record);
data = malloc(size*n);
pos = data;
for(unsigned int i = 0; i < n ; i++, pos=&pos[size])
memcpy(pos,p,size);
return (student_record *)data;
};
You may do like this.
This compiles and, I think, does what you want:
student_record *answer4(const student_record *const p, const unsigned int n)
{
unsigned int i;
student_record *const a = malloc(sizeof(student_record)*n);
for(i = 0; i < n; ++i)
{
a[i] = p[i];
}
return a;
};
Several points:
The existing array is identified as p. You want to copy from it. You probably do not want to free it (to free it is probably the caller's job).
The new array is a. You want to copy to it. The function cannot free it, because the caller will need it. Therefore, the caller must take the responsibility to free it, once the caller has done with it.
The array has n elements, indexed 0 through n-1. The usual way to express the upper bound on the index thus is i < n.
The consts I have added are not required, but well-written code will probably include them.
Altought, there are previous GOOD answers to this question, I couldn't avoid added my own. Since I got pascal programming in Collegue, I am used to do this, in C related programming languages:
void* AnyFunction(int AnyParameter)
{
void* Result = NULL;
DoSomethingWith(Result);
return Result;
}
This, helps me to easy debug, and avoid bugs like the one mention by #ysap, related to pointers.
Something important to remember, is that the question mention to return a SINGLE pointer, this a common caveat, because a pointer, can be used to address a single item, or a consecutive array !!!
This question suggests to use an array as A CONCEPT, with pointers, NOT USING ARRAY SYNTAX.
// returns a single pointer to an array:
student_record* answer4(student_record* student, unsigned int n)
{
// empty result variable for this function:
student_record* Result = NULL;
// the result will allocate a conceptual array, even if it is a single pointer:
student_record* Result = malloc(sizeof(student_record)*n);
// a copy of the destination result, will move for each item
student_record* dest = Result;
int i;
for(i = 0; i < n ; i++){
// copy contents, not address:
*dest = *student;
// move to next item of "Result"
dest++;
}
// the data referenced by "Result", was changed using "dest"
return Result;
} // student_record* answer4(...)
Check that, there is not subscript operator here, because of addressing with pointers.
Please, don't start a pascal v.s. c flame war, this is just a suggestion.
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.