Будучи новичком в C, я научился причудливому способу выделения памяти с помощью struct{}
, чтобы заменить что-то вроде ch1Buffer = calloc(u32Size, sizeof *ch1Buffer);
и поместить их вне int main{}
, чтобы повысить скорость вычислений.
Однако я получил ошибку в моей переменной x
, говоря: This declaration has no storage class or type specifier
, вы можете увидеть аннотацию сбоку от кода. Должен ли я объявить переменную x
или?
Вот мой пример кода:
#include <stdio.h>
// New way for memory allocation
struct {
float ch1Buffer;
double ch2Buffer;
double ch2newBuffer;
} *x;
x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
int main()
{
int i,n;
const int u32Size = 10;
float* ch1Buffer = NULL;
double* ch2Buffer = NULL;
double* ch2newBuffer=NULL;
int pBuffer[] = { 10,2,10,2,10,5,10,5,10,2 };
int* pi16Buffer = pBuffer;
// Old way for memory allocation
//ch1Buffer = (float*)calloc(u32Size, sizeof* ch1Buffer);
//ch2Buffer = (double*)calloc(u32Size, sizeof* ch2Buffer);
//ch2newBuffer = (double*)calloc(u32Size, sizeof * ch2Buffer);
// De-interveal the data to ch1Buffer and ch2Buffer
for (i = 0; i < u32Size/2; i++)
{
ch1Buffer[i] += pi16Buffer[i * 2];
ch2Buffer[i] += pi16Buffer[i * 2 + 1];
}
// Use memcpy to pick out the data we are interested
memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));
for (i = 0; i < 2; i++)
{
printf("a[%d] = %f\n", i, *ch2newBuffer);
ch2newBuffer++;
}
free(ch1Buffer);
free(ch2Buffer);
return 0;
}
@Jabberwocky Но даже я поставил struct{}
внутри основного, произошла другая ошибка: a value of type "void*" cannot be assigned to an entity "struct<unnamed>*"
Ты не сможешь это сделать. Ни C, ни C++ так не работают. Что касается более поздней ошибки компиляции - это потому, что вы компилируете код как C++, но на самом деле вы пишете код C. C++ требует явного приведения из void *
, которое возвращает функция C calloc
. C и C++ - два совершенно разных языка. Если вы хотите написать код на C, используйте компилятор C. Если вы намерены изучать и писать на C++, забудьте о calloc
, printf
и других и вместо этого используйте безопасные с точки зрения типов эквиваленты C++, дополнительную информацию см. в учебнике по C++.
@Кевин, тебе нужно #include <stdlib.h>
для calloc
. Но это похоже на другой вопрос. Задайте новый вопрос для этого.
Я голосую за то, чтобы закрыть этот вопрос, потому что он показывает, что ОП не предпринял никаких усилий для самостоятельного решения проблем.
Вы не можете выполнять malloc
или calloc
вне основной или любой другой функции. Вы можете объявить его в начале своего кода, если он вам нужен как глобальная переменная, но вам нужно будет выделить память, например, внутри основного.
typedef struct mystruct {
float ch1Buffer;
double ch2Buffer;
double ch2newBuffer;
}mystruct;
mystruct* x;
int main (void) {
x = calloc(10, sizeof(mystruct)); // array of your structs
if (!x) { // always check calloc return value
perror("calloc");
exit(EXIT_FAILURE);
}
/* do stuff */
return 0;
}
Кроме того, я бы предложил давать понятные имена вашим структурам для лучшего понимания того, что они представляют.
Спасибо! Но я все еще получаю ошибку в строке x = calloc(10, sizeof(mystruct));
, говоря ErroC2440'=': cannot convert from 'void *' to 'mystruct *'
Это распространенная ошибка компилятора, просто добавьте это перед calloc: x = (mystruct*)calloc(10, sizeof(mystruct));
. Явное приведение calloc к типу вашей переменной, в данном случае это mystruct*
, должно было решить вашу проблему. Это хорошая привычка всегда делать это приведение для malloc
, calloc
, потому что некоторые компиляторы не запускаются.
Спасибо, но здесь возникает проблема, с которой я сталкивался раньше при использовании struct{}
для выделения памяти. Ошибка произошла в De-interveal
части, ch1Buffer[i] += pi16Buffer[i * 2];
говоря, Exception thrown at 0x00007FF719D41A9B in Examplefordebug.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
похоже, что память не была успешно выделена?
На самом деле, я пытаюсь имитировать обработку данных, когда моя DAQ-карта получает данные по каналу 1 и каналу 2. Правило заполнения данных в памяти: ch1ch2ch1ch2.... Поэтому я написал цикл for
для разделения ' и получите эти два канала от pi16Buffer[i]
. Может быть, лучший подход для такого распределения памяти?
Задайте еще один вопрос о новой проблеме, с которой вы столкнулись. Я не уверен, что смогу помочь вам с этим, использование calloc в любом случае нормально, проблема больше не связана с его использованием. Надеюсь, моя помощь была полезной для первой части в любом случае :)
Спасибо! Я отдал тебе должное! По крайней мере, я подтвердил, что не ошибся при использовании struct{}
Это дает вам пример использования компонентов каждого члена. Как и в приведенных выше ответах, указатель определяется как глобальный и размещается в main(). Это не очень хорошая практика, просто для демонстрации.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
struct xxx {
float f1;
double d2;
double d3;
};
typedef struct xxx mytype;
mytype *x;
void print_mytype()
{
int i;
for (i=0; i<SIZE; i++) printf("x[%d] = %f, %lf, %lf\n", i, x[i].f1, x[i].d2, x[i].d3);
return;
}
void setdata()
{
int i;
for (i=0; i<SIZE; i++)
{
x[i].f1 = rand()/(float)RAND_MAX;
x[i].d2 = rand()/(double)RAND_MAX;
x[i].d3 = rand()/(double)RAND_MAX;
}
}
int main()
{
x = calloc(SIZE, sizeof(mytype));
setdata();
print_mytype();
free(x);
return 0;
}
размещенный код не компилируется!
Вот что компилятор говорит о коде:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o"
untitled1.c:9:1: warning: data definition has no type or storage class
9 | x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
| ^
untitled1.c:9:1: warning: type defaults to ‘int’ in declaration of ‘x’ [-Wimplicit-int]
untitled1.c:9:1: error: conflicting types for ‘x’
untitled1.c:8:4: note: previous declaration of ‘x’ was here
8 | } *x;
| ^
untitled1.c:9:5: warning: implicit declaration of function ‘calloc’ [-Wimplicit-function-declaration]
9 | x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
| ^~~~~~
untitled1.c:9:5: warning: incompatible implicit declaration of built-in function ‘calloc’
untitled1.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘calloc’
1 | #include <stdio.h>
+++ |+#include <stdlib.h>
2 |
untitled1.c:9:23: error: invalid type argument of unary ‘*’ (have ‘int’)
9 | x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
| ^~~
untitled1.c: In function ‘main’:
untitled1.c:33:22: warning: conversion from ‘int’ to ‘float’ may change value [-Wconversion]
33 | ch1Buffer[i] += pi16Buffer[i * 2];
| ^~
untitled1.c:38:5: warning: implicit declaration of function ‘memcpy’ [-Wimplicit-function-declaration]
38 | memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));
| ^~~~~~
untitled1.c:38:5: warning: incompatible implicit declaration of built-in function ‘memcpy’
untitled1.c:2:1: note: include ‘<string.h>’ or provide a declaration of ‘memcpy’
1 | #include <stdio.h>
+++ |+#include <string.h>
2 |
untitled1.c:47:5: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
47 | free(ch1Buffer);
| ^~~~
untitled1.c:47:5: warning: incompatible implicit declaration of built-in function ‘free’
untitled1.c:47:5: note: include ‘<stdlib.h>’ or provide a declaration of ‘free’
untitled1.c:13:11: warning: unused variable ‘n’ [-Wunused-variable]
13 | int i,n;
| ^
Compilation failed.
Предложите вам исправить те проблемы в коде, которые вы можете, прежде чем спрашивать нас о каких-либо проблемах, которые вы не можете исправить.
Как говорится в сообщениях об ошибках:
добавить заявление:
#include <stdlib.h>
добавить заявление:
#include <string.h>
Мы вряд ли поможем вам, когда код, который вы публикуете, ясно указывает на то, что вы не приложили никаких усилий для решения проблемы (проблем) самостоятельно.
Спасибо за ваш совет, кроме того, если вы думаете, что я не приложил никаких усилий, вы можете решить не отвечать или беспокоить;)
@Kevin, когда вы публикуете код, который не показывает никаких усилий (с вашей стороны), вы будете отмечены и увидите комментарии о «никаких усилиях». Предложите: исправьте те вещи, которые вы можете, например, отсутствующие файлы заголовков, а затем опубликуйте раздел «редактирование» в своем вопросе.
Вы не можете вызывать функции при инициализации глобальных переменных в C.