When I run debugging it points to the line: 105 (and writes "segmentation fault" in the left corner). I don't know what does red line in "Call stack" window mean...
Please, tell waht it is and where can I read more about it.
Here is the function's code:
/* Separates stereo file's samples to L and R channels. */
struct LandR sepChannels_8( unsigned char *smp, unsigned long N, unsigned char *L, unsigned char *R, struct LandR LRChannels )
{
int i;
if ( N % 2 == 0 ) // Each channel's (L,R) number of samles is 1/2 of all samples.
{
L = malloc(N / 2);
R = malloc(N / 2);
}
else
if ( N % 2 == 1 )
{
L = malloc(N + 1 / 2);
R = malloc(N + 1 / 2);
}
int m = 0;
for ( i = 0; i < N; i++ ) // separating
{
L[m] = smp[2 * i + 0]; // THIS IS THE "LINE: 105"
R[m] = smp[2 * i + 1];
m++;
}
return LRChannels;
}
And here is sreenshot of the windows (easier to show it instead of trying to describe)
The line in red is your call stack: Basically, it's telling you that the problem occurred inside the the sepChannels_8() function, which was called from main(). You have, in fact, several bugs in your sepChannels_8() function.
Here is my analysis:
struct LandR sepChannels_8(unsigned char *smp, unsigned long N, unsigned char *L, unsigned char *R, struct LandR LRChannels)
sepChannels_8 is a function that takes five arguments of varying types and returns a value of type struct LandR. However, it's not clear what the five arguments passed to the function are. unsigned char *smp appears to be a pointer to your audio samples, with unsigned long N being the total number of samples. But unsigned char *L, unsigned char *R, and struct LandR LRChannels, it's not at all clear what the point is. You don't use them. unsigned char *L and unsigned char *R, your function promptly discards any passed-in pointers, replacing them with memory allocated using malloc(), which is then thrown away without being free()d, and the only thing you do with struct LandR LRChannels is simply return it unchanged.
{
int i;
if ( N % 2 == 0 ) // Each channel's (L,R) number of samles is 1/2 of all samples.
{
L = malloc(N / 2);
R = malloc(N / 2);
}
else
if ( N % 2 == 1 )
{
L = malloc(N + 1 / 2);
R = malloc(N + 1 / 2);
}
Now this is interesting: If the passed-in unsigned long, N, is an even number, you use malloc() to allocate two blocks of storage, each N / 2 in size, and assign them to L and R. If N is not even, you then double-check to see if it's an odd number, and if it is, you use malloc() to allocate two blocks of storage, each N in size, and assign them to L and R. I think you may have intended to allocate two blocks of storage that were each (N + 1) / 2 in size, but multiplication and division happen before addition and subtraction, so that's not what you get. You also fail to account for what happens if N is neither even nor odd. That's OK, because after all, that's an impossible condition... so why are you testing for the possibility?
int m = 0;
for ( i = 0; i < N; i++ ) // separating
{
L[m] = smp[2 * i + 0]; // THIS IS THE "LINE: 105"
R[m] = smp[2 * i + 1];
m++;
}
Mostly pretty standard: you've got a loop, with a counter, and arrays to traverse. However, your terminating condition is wrong. You're walking down your smp data two steps at a time, and you're doing it by multiplying your array index, so your index counter needs to run from 0 to N / 2, not from 0 to N. (Also, you need to account for that last item, if N was odd...). Further, you're using m and i for the same thing at the same time. One of them is unnecessary, and redundant, and not needed, and extra.
return LRChannels;
}
And, return the LRChannels struct that was passed in to the function, unmodified. At the same time, you're discarding the L and R variables, which contain pointers to malloc()-allocated storage, now lost.
What were L and R supposed to be? It almost looks as though they're supposed to be unsigned char **, so you could give your allocated storage back to the caller by storing the pointers through them... or perhaps struct LandR has two elements that are pointers, and you were intending to save L and R in the struct before returning it? for L and R, and LRChannels, I don't see why you're passing them to the function at all. You might as well make them all automatic variables inside the function just as int i and int m are.
You have malloced N/2 elements in the array but in the loop, your counter goes from 0 to N. And that will imply that you are trying to access elements from 0 to N because you increment m on every iteration. Obviously, you will get a seg fault.
What is the value of 'smp'?
It either needs to have been allocated prior to the call to sepChannels_8(), or point to a valid placeholder.
Related
This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 3 years ago.
Is there a way, I can use of strlen() to find the length of the arrays, instead of specifying in the loop.
First Code: Working With x < 4 Which is the size of the array of temps[4].
#include <stdio.h>
#include <string.h>
int main(){
float temps[4] = {72.5, 73.4, 74.7, 75.2};
int x;
printf("Local Temperatures\n");
for(x = 1; x < 4; x++){
printf("Station %d: %.1f\n",x,temps[x]);
}
}
My Second Code, Not Working, But Looking At What, I Am Trying To achieve with strlen() to find the size of the array.:
#include <stdio.h>
#include <string.h>
int main(){
float temps[4] = {72.5, 73.4, 74.7, 75.2};
int x;
float size;
size = temps;
printf("Local Temperatures\n");
for(x = 1; x < strlen(size); x++){
printf("Station %d: %.1f\n",x,size[x]);
}
}
strlen is effectively an optimized version of the following:
size_t len = 0;
const char *p = s;
while (!*p) {
++len;
++p;
}
You can easily adapt that.
size_t len = 0;
const float *p = s;
while (*p != 0.0) {
++len;
++p;
}
Of course, that means you need a sentinel value just like you had for the string.
float temps[] = { 72.5, 73.4, 74.7, 75.2, 0.0 };
While you can use a value other than 0.0 as your sentinel value, using a sentinel value might not be desirable, so you might not really want to take the same approach as one does for strings.
For an array (as opposed to a pointer), you can use the following to determine the number of elements in the array:
sizeof(a)/sizeof(*a)
That means you can use the following to determine the number of elements in temps:
sizeof(temps)/sizeof(*temps)
Simple method is to get the size of a array is by sizeof(temps)/sizeof(temps[0])
something like,
for(x = 0; x < sizeof(temps)/sizeof(temps[0]); x++){
printf("Station %d: %.1f\n",x,temps[x]);
}
Note: In your snippet array access is done from 1 to (size) instead 0 to (size-1) which is out of bound access.
Short answer: no.
strlen expects an argument of type char *, which points to the first character of a string, which is a sequence of character values including a zero-valued terminator. strlen returns the number of characters before the terminator:
/**
* A naive implementation of strlen. Actual implementations
* are a little more clever.
*/
size_t strlen( const char *str )
{
size_t count = 0;
while( str[count] )
count++;
return count;
}
The important thing to remember is that strlen returns the length of the string, not the size of the array containing the string. If you have something like
char foo[1024] = “bar”;
the strlen( foo ); returns 3.
If you tried to pass an integer or floating point array to strlen the compiler would yell at you because of the wrong argument type. You could work around this by casting the argument to char *, but you would still likely get a wrong answer, not only because integer and float types are multiple chars wide, but also because such a value may have an embedded zero-valued byte. For example, the integer value 16 is represented as the bytes 0x00, 0x00, 0x00, 0x10. If that’s the first element of your integer array, then strlen would return 0 on a big-endian platform and 1 on a little-endian platform.
If you defined the array, then you know how big it is. If you’re writing a function that receives an array argument, then you must either also receive the size as a separate argument, or you must rely on the presence of a sentinel value in the array.
Just do this to get the length of your float array,
int main()
{
float ar[4] = {1.1,1.2,1.3,1.4};
float b;
printf("Array Size : %d\n",sizeof(ar)/sizeof(b));
return 0;
}
You'll get the total number of element of your array , which you can use further in a loop to print the elements of array.
Note: Do not Use sizeof in case of pointers.
strlen() takes a "const char *" type value as argument. So it cannot be used with integer or float arrays.
I am performing Compressed Sparse Raw Matrix Vector multiplications (CSR SPMV): This involves dividing the array A into multiple chunks, then pass this chunk by reference to a function, however only the first part of the array (A[0] first chunk starting the beginning of the array) is modified. However starting from the second loop A[0 + chunkIndex], when the function reads the sub array it jumps and reads a different address beyond the total array address range, although the indices are correct.
For reference:
The SPMV kernel is:
void serial_matvec(size_t TS, double *A, int *JA, int *IA, double *X, double *Y)
{
double sum;
for (int i = 0; i < TS; ++i)
{
sum = 0.0;
for (int j = IA[i]; j < IA[i + 1]; ++j)
{
sum += A[j] * X[JA[j]]; // the error is here , the function reads diffrent
// address of A, and JA, so the access
// will be out-of-bound
}
Y[i] = sum;
}
}
and it is called this way:
int chunkIndex = 0;
for(size_t k = 0; k < rows/TS; ++k)
{
chunkIndex = IA[k * TS];
serial_matvec(TS, &A[chunkIndex], &JA[chunkIndex], &IA[k*TS], &X[0], &Y[k*TS]);
}
assume I process (8x8) Matrix, and I process 2 rows per chunk, so the loop k will be rows/TS = 4 loops, the chunkIndex and array passed to the function will be as following:
chunkIndex: 0 --> loop k = 0, &A[0], &JA[0]
chunkIndex: --> loop k = 1, &A[16], &JA[16] //[ERROR here, function reads different address]
chunkIndex: --> loop k = 2, &A[32], &JA[32] //[ERROR here, function reads different address]
chunkIndex: --> loop k = 3, &A[48], &JA[48] //[ERROR here, function reads different address]
When I run the code, only the first chunk executes correctly, the other 3 chunks memory are corrupted and the array pointers jump into boundary beyond the array size.
I've checked all indices manually, of all the parameter, they are all correct, however when I print the addresses they are not the same. (debugging this for 3 days now)
I used valgrind and it reported:
Invalid read of size 8 and Use of uninitialised value of size 8 at the sum += A[j] * X[JA[j]]; line
I compiled it with -g -fsanitize=address and I got
heap-buffer-overflow
I tried to access these chunks manually outside the function, and they are correct, so what can cause the heap memory to be corrupted like this ?
The code is here, This is the minimum I can do.
The problem was that I was using global indices (indices inside main) when indexing the portion of the array (chunk) passed to the function, hence the out-of-bound problem.
The solution is to start indexing the sub-arrays from 0 at each function call, but I had another problem. At each function call, I process TS rows, each row has different number of non-zeros.
As an example, see the picture, chunk 1, sorry for my bad handwriting, it is easier this way. As you can see we will need 3 indices, one for the TS rows proceeded per chunk i , and the other because each row has different number of non-zeros j, and the third one to index the sub-array passed l, which was the original problem.
and the serial_matvec function will be as following:
void serial_matvec(size_t TS, const double *A, const int *JA, const int *IA,
const double *X, double *Y) {
int l = 0;
for (int i = 0; i < TS; ++i) {
for (int j = 0; j < (IA[i + 1] - IA[i]); ++j) {
Y[i] += A[l] * X[JA[l]];
l++;
}
}
}
The complete code with test is here If anyone has a more elegant solution, you are more than welcome.
I have a very, very long array and I have to get the minimum difference of all possible combinations of 2 elements.
This is my code:
[...]
int diff = 1000000; // a very big difference that i'm sure is too big
int tmpDiff; // swap
//Compare
for (size_t i = 0; i < N; i++) { // I try every combination of 2 elements of array
for (size_t j = i + 1; j < N; j++) { // don't repeat same elements
tmpDiff = abs(array[i] - array[j]); // get the difference
if (diff > tmpDiff) { // if it is smaller is the difference i need
diff = tmpDiff;
}
}
}
[...]
It takes too much time. How could we optimize performances?
Sort the array first. Then you only need to compare consecutive values. And you don't even need to use abs() as you know which of the two elements it the bigger one.
If the array must not be changed, copy it first (not shown below).
#include <limits.h>
#include <stdlib.h>
// compare function for integer, compatible with qsort
int int_cmp(const void *a, const void *b)
{
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
return *ia - *ib;
}
...
int diff = INT_MAX;
int d;
// sort
qsort(array, N, sizeof(array[0]), int_cmp);
// compare consecutive elements
for (size_t i = 1; i < N; i++) {
d = array[i] - array[i - 1];
if (d < diff)
diff = d;
}
Update
qsort sorts an array using the Quicksort algorithm. The cost of the sorting is of the order O(n ln n) as opposed to O(n^2) if you have two nested for loops. For bigger arrays (n > 100), this can make a huge difference. Just do the math: approx. 500 vs. 10,000.
The comparison function passed to qsort is always tricky as qsort is written such that it works with arrays of any type. The function is passed the address of (pointer to) two elements in the array. For small types such as integer, it would be handy if it passed the integers directly. But instead, you have to deal with the address. So what you do is two things:
Convert the pointer to a more specific type, i.e. from a pointer of any type (void*) to a pointer to an integer (int*).
Dereference the pointer, i.e. get the effective value by using the * operator, in this case *ia and *ib.
The functions needs to return a number less than 0 if the first integer is smaller than the second one, 0 if they are equal and a number greater than 0 if the second number is bigger. So an old trick comes in handy: just return the difference between the first and second number.
This is my first time asking so please be gentle lol.
So I am trying to better understand arrays in C. Is there a way I can add an element to an array without using a for loop? The problem is I want to add a new element to the end of the array, but without knowing the size of the array.
So I already have this:
#include <stdlib.h> //not sure if needed but put it just in case
int main(void):
float real[20];
real[]={1,2,3,4,5};
I want to add the number 6 to the array, but I don't want to use real[5]=6. Is there another way to add an element to the end of the array without a loop checking if each element in the array until the element is null? Thanks for your help in advance!
C arrays don't know about their length. If you need arrays that can grow and shrink, you have to keep extra information on how long your active array is. An array that is created on the stack like so:
real array[20] = {1, 2, 3};
will contain twenty elements, the first three initialised with concrete values, the rest initialised to zero. If you want to consider this array as an array of initially three values that can hold up to 20 values, you have to keep the actual array length as an extra variable:
real array[20] = {1, 2, 3};
int narray = 3;
You can then append a value. Take care not to overflow that maximum storage of 20 elements:
if (narray < 20) array[narray++] = 9;
You can read the last value and remove it from the array:
if (narray) printf("%g\n", array[--narry]);
Here, you have to take care not to underflow the array. (Also, don't decrement narray more than once in the same expression, which will lead to undefined behaviour.)
If you write a function that operates on the array, pass both array and length:
void array_print(float array[], int n)
{
int i;
for (i = 0; i < n; i++) {
if (i) printf(", ");
printf("%g", array[i]);
}
printf("\n");
}
and call it like so:
array_print(array, narray);
Another approach is to keep a sentinel value like 0.0. This can be useful in some cases, but it has the disadvantage that you have to traverse the whole array to find out the length. It also removes the sentinel from the range of valid values that your array can hold.
The advantage here is, of course, that the array is "self-contained", i.e. you don't have to pass array and length to a function; just the array is enough. When appending you still have to take care not to overflow the maximum storage, which makes this approach cumbersome.
The only way is to keep a pointer to the next free position in the array. For example
#include <stdio.h>
float * copy( const float *src, size_t n, float *dst )
{
while ( n-- ) *dst++ = *src++;
return dst;
}
int main(void)
{
float real[20];
float *p = real;
p = copy( ( float [] ){ 1, 2, 3, 4, 5 }, 5, p );
p = copy( ( float [] ){ 6, 7 }, 2, p );
for ( float *q = real; q != p; ++q ) printf( "%1.1f ", *q );
printf( "\n" );
return 0;
}
The output is
1.0 2.0 3.0 4.0 5.0 6.0 7.0
You always can check whether p points within the array using condition
p < real + 20
The other approach is to use a structure that contains an array. For example
struct Array
{
enum { N = 20 };
float real[N];
size_t n; /* current number of filled elements */
};
With a little help of the preprocessor, you can use a compound literal to get the size:
int main(void)
{
#define REAL_VALUES 1, 2, 3, 4, 5
float real[20] = {REAL_VALUES};
real[sizeof((float[]){REAL_VALUES}) / sizeof(float)] = 6;
return 0;
}
In C you can get the length of an array with the expression sizeof (array) / sizeof (array)[0], or even better, by defining a macro:
#define LEN(array) \
((int) (sizeof (array) / sizeof (array)[0]))
What you describe is not adding an element to the end of the array but rather adding an element after the last element inserted. For that you need a variable that keeps track of the element count:
int count = 0;
float x;
...
if (count < LEN(real)) {
real[count] = x;
count++;
}
Observe, however, that once you have passed the array to a function its length is gone, so you need to pass the array length to the function as well:
void foo(float a[], int len);
...
foo(real, LEN(real));
You can use memset() to make space for your element in your array and then insert your element at specific position.
Here is sample code below.
/*Make space for number to insert.*/
memmove(&arr[pos+1],&arr[pos],(ARR_SIZE+1-pos)*sizeof(int));
arr[pos] = num;/*insert the number.*/
Full code snipet could be found here InsertElement
I'm trying to allocate a large space of contiguous memory in C and print this out to the user. My strategy for doing this is to create two pointers (one a pointer to double, one a pointer to pointer to double), malloc one of them to the entire size (m * n) in this case the pointer to pointer to double. Then malloc the second one to the size of m. The last step will be to iterate through the size of m and perform pointer arithmetic that would ensure the addresses of the doubles in the large array will be stored in contiguous memory. Here is my code. But when I print out the address it doesn't seem to be in contiguous (or in any sort of order). How do i print out the memory addresses of the doubles (all of them are of value 0.0) correctly?
/* correct solution, with correct formatting */
/*The total number of bytes allocated was: 4
0x7fd5e1c038c0 - 1
0x7fd5e1c038c8 - 2
0x7fd5e1c038d0 - 3
0x7fd5e1c038d8 - 4*/
double **dmatrix(size_t m, size_t n);
int main(int argc, char const *argv[])
{
int m,n,i;
double ** f;
m = n = 2;
i = 0;
f = dmatrix(sizeof(m), sizeof(n));
printf("%s %d\n", "The total number of bytes allocated was: ", m * n);
for (i=0;i<n*m;++i) {
printf("%p - %d\n ", &f[i], i + 1);
}
return 0;
}
double **dmatrix(size_t m, size_t n) {
double ** ptr1 = (double **)malloc(sizeof(double *) * m * n);
double * ptr2 = (double *)malloc(sizeof(double) * m);
int i;
for (i = 0; i < n; i++){
ptr1[i] = ptr2+m*i;
}
return ptr1;
}
Remember that memory is just memory. Sounds trite, but so many people seem to think of memory allocation and memory management in C as being some magic-voodoo. It isn't. At the end of the day you allocate whatever memory you need, and free it when you're done.
So start with the most basic question: If you had a need for 'n' double values, how would you allocate them?
double *d1d = calloc(n, sizeof(double));
// ... use d1d like an array (d1d[0] = 100.00, etc. ...
free(d1d);
Simple enough. Next question, in two parts, where the first part has nothing to do with memory allocation (yet):
How many double values are in a 2D array that is m*n in size?
How can we allocate enough memory to hold them all.
Answers:
There are m*n doubles in a m*n 2D-matrix of doubles
Allocate enough memory to hold (m*n) doubles.
Seems simple enough:
size_t m=10;
size_t n=20;
double *d2d = calloc(m*n, sizeof(double));
But how do we access the actual elements? A little math is in order. Knowing m and n, you can simple do this
size_t i = 3; // value you want in the major index (0..(m-1)).
size_t j = 4; // value you want in the minor index (0..(n-1)).
d2d[i*n+j] = 100.0;
Is there a simpler way to do this? In standard C, yes; in C++ no. Standard C supports a very handy capability that generates the proper code to declare dynamically-sized indexible arrays:
size_t m=10;
size_t n=20;
double (*d2d)[n] = calloc(m, sizeof(*d2d));
Can't stress this enough: Standard C supports this, C++ does NOT. If you're using C++ you may want to write an object class to do this all for you anyway, so it won't be mentioned beyond that.
So what does the above actual do ? Well first, it should be obvious we are still allocating the same amount of memory we were allocating before. That is, m*n elements, each sizeof(double) large. But you're probably asking yourself,"What is with that variable declaration?" That needs a little explaining.
There is a clear and present difference between this:
double *ptrs[n]; // declares an array of `n` pointers to doubles.
and this:
double (*ptr)[n]; // declares a pointer to an array of `n` doubles.
The compiler is now aware of how wide each row is (n doubles in each row), so we can now reference elements in the array using two indexes:
size_t m=10;
size_t n=20;
double (*d2d)[n] = calloc(m, sizeof(*d2d));
d2d[2][5] = 100.0; // does the 2*n+5 math for you.
free(d2d);
Can we extend this to 3D? Of course, the math starts looking a little weird, but it is still just offset calculations into a big'ol'block'o'ram. First the "do-your-own-math" way, indexing with [i,j,k]:
size_t l=10;
size_t m=20;
size_t n=30;
double *d3d = calloc(l*m*n, sizeof(double));
size_t i=3;
size_t j=4;
size_t k=5;
d3d[i*m*n + j*m + k] = 100.0;
free(d3d);
You need to stare at the math in that for a minute to really gel on how it computes where the double value in that big block of ram actually is. Using the above dimensions and desired indexes, the "raw" index is:
i*m*n = 3*20*30 = 1800
j*m = 4*20 = 80
k = 5 = 5
======================
i*m*n+j*m+k = 1885
So we're hitting the 1885'th element in that big linear block. Lets do another. what about [0,1,2]?
i*m*n = 0*20*30 = 0
j*m = 1*20 = 20
k = 2 = 2
======================
i*m*n+j*m+k = 22
I.e. the 22nd element in the linear array.
It should be obvious by now that so long as you stay within the self-prescribed bounds of your array, i:[0..(l-1)], j:[0..(m-1)], and k:[0..(n-1)] any valid index trio will locate a unique value in the linear array that no other valid trio will also locate.
Finally, we use the same array pointer declaration like we did before with a 2D array, but extend it to 3D:
size_t l=10;
size_t m=20;
size_t n=30;
double (*d3d)[m][n] = calloc(l, sizeof(*d3d));
d3d[3][4][5] = 100.0;
free(d3d);
Again, all this really does is the same math we were doing before by hand, but letting the compiler do it for us.
I realize is may be a bit much to wrap your head around, but it is important. If it is paramount you have contiguous memory matrices (like feeding a matrix to a graphics rendering library like OpenGL, etc), you can do it relatively painlessly using the above techniques.
Finally, you might wonder why would anyone do the whole pointer arrays to pointer arrays to pointer arrays to values thing in the first place if you can do it like this? A lot of reasons. Suppose you're replacing rows. swapping a pointer is easy; copying an entire row? expensive. Supposed you're replacing an entire table-dimension (m*n) in your 3D array (l*n*m), even more-so, swapping a pointer: easy; copying an entire m*n table? expensive. And the not-so-obvious answer. What if the rows widths need to be independent from row to row (i.e. row0 can be 5 elements, row1 can be 6 elements). A fixed l*m*n allocation simply doesn't work then.
Best of luck.
Never mind, I figured it out.
/* The total number of bytes allocated was: 8
0x7fb35ac038c0 - 1
0x7fb35ac038c8 - 2
0x7fb35ac038d0 - 3
0x7fb35ac038d8 - 4
0x7fb35ac038e0 - 5
0x7fb35ac038e8 - 6
0x7fb35ac038f0 - 7
0x7fb35ac038f8 - 8 */
double ***d3darr(size_t l, size_t m, size_t n);
int main(int argc, char const *argv[])
{
int m,n,l,i;
double *** f;
m = n = l = 10; i = 0;
f = d3darr(sizeof(l), sizeof(m), sizeof(n));
printf("%s %d\n", "The total number of bytes allocated was: ", m * n * l);
for (i=0;i<n*m*l;++i) {
printf("%p - %d\n ", &f[i], i + 1);
}
return 0;
}
double ***d3darr(size_t l, size_t m, size_t n){
double *** ptr1 = (double ***)malloc(sizeof(double **) * m * n * l);
double ** ptr2 = (double **)malloc(sizeof(double *) * m * n);
double * ptr3 = (double *)malloc(sizeof(double) * m);
int i, j;
for (i = 0; i < l; ++i) {
ptr1[i] = ptr2+m*n*i;
for (j = 0; j < l; ++j){
ptr2[i] = ptr3+j*n;
}
}
return ptr1;
}