Segmentation fault - c

In C, when I try to run this program, I get a "Segmentation fault". What does it mean? How can I fix this?
Tag tagNewDataPoint(const double x[MAX_DIMENSION],
const double w[MAX_DIMENSION],
const int d)
{
int separator_arr,point_arr;
double result = 0;
for (separator_arr=0;separator_arr<d;separator_arr++)
{
for (point_arr=0;point_arr<d;separator_arr++)
{
result += w[separator_arr]*x[point_arr];
}
}
if (result <0)
{
return NEG;
}
else if (result >0)
{
return POS;
}
else
{
return NOTAG;
}
}

This:
for (point_arr=0;point_arr<d;separator_arr++)
should be:
for (point_arr=0;point_arr<d;point_arr++)
You increment the separator_arr, but checks the pointer_arr value (which is never changed) soon enough separator_arr is too big, and your address is invalid.

You have index crosstalk.
for (point_arr=0;point_arr<d;separator_arr++)
should be
for (point_arr=0;point_arr<d;point_arr++)

Related

Waiting for character in string

I am currently working on a project that will be used to test whether an instrument is within tolerance or not. My test equipment will put the DUT (Device Under Test) into a "Test Mode" where it will repeatedly send a string of data every 200ms. I want to receive that data, check is is within tolerance and give it a pass or fail.
My code so far (I've edited a few things out like .h files and some work related bits!):
void GetData();
void CheckData();
char Data[100];
int deviceId;
float a;
float b;
float c;
void ParseString(const char* stringValue)
{
char* token = NULL;
int tokenPlace = 0;
token = strtok((char *) stringValue, ",");
while (token != NULL) {
switch (tokenPlace) {
case 0:
deviceId = atoi(token);
break;
case 1:
a= ((float)atoi(token)) / 10.0f;
break;
case 2:
b= ((float)atoi(token)) / 100.0f;
break;
case 3:
c= ((float)atoi(token)) / 10.0f;
break;
}
tokenPlace++;
token = strtok(NULL, ",");
}
}
void GetData()
{
int x = UART.scanf("%s,",Data);
ParseString(Data);
if (x !=0) {
UART.printf("Device ID = %i\n\r", deviceId);
UART.printf("a= %.1f\n\r", a);
UART.printf("s= %.2f\n\r", b);
UART.printf("c= %.1f\n\n\r", c);
}
if (deviceId <= 2) {
CheckData();
} else {
pc.printf("Device ID not recognised\n\n\r");
}
}
void CheckData()
{
if (a >= 49.9f && a< = 50.1f) {
pc.printf("a Pass\n\r");
} else {
pc.printf("a Fail\n\r");
}
if (b >= 2.08f && b <= 2.12f) {
pc.printf("b Pass\n\r");
} else {
pc.printf("b Fail\n\r");
}
if (c >= 20.0f && c <= 25.0f) {
pc.printf("c Pass\n\n\r");
} else {
pc.printf("c Fail\n\n\r");
}
if (deviceId == 0) {
(routine1);
} else if (deviceId == 1) {
(routine2);
} else if (deviceId == 2) {
(Routine3);
}
}
int main()
{
while(1) {
if(START == 0) {
wait(0.1);
GetData();
}
}
}
And this works absolutely fine. I am only printing the results to a serial terminal so I can check the data is correct to make sure it is passing and failing correctly.
My issue is every now and then the START button happens to be pressed during the time the string is sent and the data can be corrupt, so the deviceId fails and it will say not recognised. This means I then have to press the start button again and have another go. A the moment, it's a rare occurrence but I'd like to get rid of it if possible. I have tried adding a special character at the beginning of the string but this again gets missed sometimes.
Ideally, when the start button is pressed, I would like it to wait for this special character so it knows it is at the beginning of the string, then the data would be read correctly, but I am unsure how to go about it.
I have been unsuccessful in my attempts so far but I have a feeling I am overthinking it and there is a nice easy way to do it. Probably been staring at it too long now!
My microcontroller is STM32F103RB and I am using the STM Nucleo with the mBed IDE as it's easy and convenient to test the code while I work on it.
You can use ParseString to return a status indicating whether a complete string is read or not.
int ParseString(const char* stringValue)
{
/* ... your original code ... */
/* String is complete if 4 tokens are read */
return (tokenPlace == 4);
}
Then in GetData use the ParseString return value to determine whether to skip the string or not.
void GetData()
{
int x = UART.scanf("%s,",Data);
int result = ParseString(Data);
if (!result) {
/* Did not get complete string - just skip processing */
return;
}
/* ... the rest of your original code ... */
}

Differentiate between return value and error in C

I am trying to write a function that takes a linked list, an index and returns the value at the index+1 position.
int getData(list *l, int index) {
if(...) {
...
return result; // this could be -1
}
else {
return -1;
}
}
In C you return a value of -1 when the function fails (as a way to let the user know that the call failed because of bad input). However, because the return type of this function is int, it includes the value of -1 (-1 as a number, as well ass -2, -3 etc)
My question is: Is there a mechanism in which you can return from your function and make the user of the function aware that the returned value is in fact an error and not a value?
Return the value by passing a pointer and make the return value an error statement:
int getData(list *l, int inIndex, int* outIndex) {
if(...) {
...
*outIndex = result;
return 0;
}
else {
return -1;
}
}

Recursive function is not working with a pointer

This function aims to return the number of zeroes in a number, num. The function rCountZeros2() passes the result through
the pointer parameter result.
`
void rCountZeros2(int num, int *result)
{
if (num==0)
return;
else
{
if (num%10==0){
(*result)++;
}
rCountZeros2(num/10, result);
}
}
`
See when you are invoking rCountZeros2() , my guess is value in variable result is not zero.It may be some garbage value or some other value from previous computation.However with details you have provided it is difficult to provide exact answer.
Kindly try the following standalone program, I got correct answer using your code
void rCountZeros2(int num, int *result)
{
if (num==0)
return;
else
{
if (num%10==0){
(*result)++;
}
rCountZeros2(num/10, result);
}
}
int main()
{
int result = 0;
int num=12300000;
rCountZeros2(num, &result);
printf("number of zeros in %d = %d",num ,result);
}

Is it normal that void pointers give warnings?

I'm doing a school project and i'm going out of my away to get a better grade
With that being said i'm trying to use void pointers and type casting to make my program as general as possible for any type of scenario i throw at it.
I did some code and it does everything it should do but it gives me some warnings whenever i rebuild all but no warning when i compile it.
Side note: I know i am returning an integer to a pointer, but i can't return an local pointer otherwise it will not give me the result i need.
#define VERDADEIRO 1
#define FALSO 0
void * removido(info* tab,int pos)
{
if(strcmp(tab[pos].nome,REMOVIDO) != 0)
{
return FALSO;
}
else
{
return VERDADEIRO;
}
}
void * vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)!= 0)
{
return FALSO;
}
else
{
return VERDADEIRO;
}
}
int listar(info * tab)
{
int i,c=0,j;
for(i=0;i<HASHTAM;i++)
{
if((int *)removido(tab,i) ==FALSO && (int *)vazio(tab,i)==FALSO)
{
printf("Nome: %s",tab[i].nome);
printf("NIF: %d\n",tab[i].NIF);
printf("Morada: %s",tab[i].morada);
printf("Telefone: %d\n",tab[i].telefone);
printf("Codigo Postal: %d - %d\n",tab[i].codigopostal/1000,tab[i].codigopostal%1000);
printf("Data de nasicmento: %d - %d - %d\n",tab[i].datanascimento%100,(tab[i].datanascimento%10000)/100,tab[i].datanascimento/10000);
printf("Associado: %s\n",tab[i].infoassociado.associado);
if(associado(tab,i)==VERDADEIRO)
{
for(j=0;j<10;j++)
{
printf("Cota de %d anos atras - Estado: %c\n",j+1,tab[i].infoassociado.cotas[j]);
}
}
c++;
}
}
The warnings are comparison between pointer and integer and return makes pointer from integer without a cast.
No, they're not normal. They're telling you that you're using pointers incorrectly. FALSO and VERDADEIRO are not pointers.
Functions which return true and false are not a good use of void pointers, or pointers in general. Nor do you have to define your own true and false values. Instead use the booleans true and false from stdbool.h. (Note: this was added in C99 and some professors cling to the C90 standard.)
#include <stdbool.h>
bool removido(info* tab,int pos)
{
if(strcmp(tab[pos].nome,REMOVIDO) != 0) {
return false;
}
else {
return true;
}
}
bool vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)!= 0) {
return false;
}
else {
return true;
}
}
And then later you can simply check whether the return value is true or false using normal boolean checks.
if( !removido(tab,i) && !vazio(tab,i) ) {
...
}
Note that double negatives make code difficult to understand. If you check for equality and return true, that is simpler.
bool vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)== 0) {
return true;
}
else {
return false;
}
}
To really simplify the code, you can take advantage that strcmp(...) == 0 returns a boolean (technically it returns 0 or 1 which can be used as a boolean) and reduce those functions to one line.
bool removido(info* tab,int pos)
{
return strcmp(tab[pos].nome,REMOVIDO) == 0;
}

Remove the duplicate from a String Using Pointers

#include<stdio.h>
char *removedps(char *x)
{
int Ar[256] = {0};
int ip=0;
int op=0;
char temp;
while(*(x+ip))
{
temp = (*(x+ip));
if (!Ar[temp]) {
Ar[temp] = 1;
*(x+ip) = *(x+op);
op++;
}
ip++;
*(x+op) = '\0';
}
return x;
}
int main()
{
char lo[] = "0001";
printf("%s",removedps(lo));
}
My code is not working
I have tried hard to see the error
All I GET IS the first character .
My idea is simple
make an array of 256 places
insert Zero into them
Then insert 1 for each character inside the string (on that position of the array)
your assignment looks to be the error here.
op is "out postiion", ip is "in position"
so it should be
*(x+op) = *(x+ip);
not the other way.
because *(x+op) = '\0';
is always run every iteration of the loop.
I'd probablly do it more like this ( using your method, which I probablly wouldn't use personally)
char *removedps(char *x)
{
int Ar[256] = {0};
char* start = x;
while(*x)
{
if (Ar[*x])
{ // remove the repeated character
memmove(x, x+1, strlen(x));
}
else
{
Ar[*x] = 1;
x++;
}
}
return start;
}
also, I'd name it remove_duplicate_chars or something, not a fan of cryptic abbreviations.
At the end of the loop, you do *(x+op)='\0';, and then, in the next iteration, you do *(x+ip)=*(x+op);, so from the 2sd iteration, you put there 0.
try do something like:
for (op=ip=0;x[ip];ip++) {
if (!Ar[x[ip]]++) x[op++]=x[ip];
}
x[op]=0;

Resources