В продолжение изучения языка си я встретил такой код: "Split string with delimiters in C" Он отлично работает, но когда я компилирую программу, то получаю следующее предупреждение:
split.c: In function ‘split’: split.c:44:7: warning: assignment from incompatible pointer type [enabled by default] res = (char *)calloc(count,sizeof(char));
Я, конечно, заметил, что-то неправильно с распределением памяти и указателями - calloc для указателя на указатель, но я не могу понять, что именно неправильно и как сделать без багов. Не могли бы вы помочь прояснить ситуацию?
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
/**
* splits str on delim and dynamically allocates an array of pointers.
*
* On error -1 is returned, check errno
* On success size of array is returned, which may be 0 on an empty string
* or 1 if no delim was found.
*
* You could rewrite this to return the char ** array instead and upon NULL
* know it's an allocation problem but I did the triple array here. Note that
* upon the hitting two delim's in a row "foo,,bar" the array would be:
* { "foo", NULL, "bar" }
*
* You need to define the semantics of a trailing delim Like "foo," is that a
* 2 count array or an array of one? I choose the two count with the second entry
* set to NULL since it's valueless.
* Modifies str so make a copy if this is a problem
*/
size_t split(
char * str,
char delim,
char ***array,
size_t *length
)
{
char *p = NULL;
char **res = NULL;
size_t count = 0;
p = str;
// Count occurance of delim in string
while((p=strchr(p,delim)) != NULL) {
*p = 0; // Null terminate the deliminator.
p++; // Skip past our new null
count++;
}
// allocate dynamic array
if(count > 0){
res = (char *)calloc(count,sizeof(char));
if(!res){
printf("Error: can't allocate memory!");
exit(EXIT_FAILURE);
}
}else{
return(0);
}
p = str;
for(size_t k=0; k<count; k++ ) {
if( *p ) res[k] = p; // Copy start of string
p = strchr(p, 0 ); // Look for next null
p++; // Start of next string
}
*array = res;
*length = count;
return(0);
}
int main(void)
{
char **res = NULL;
size_t count = 0;
size_t rc = 0;
char str[] = "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC,";
rc = split(str,',',&res,&count );
if(rc) {
printf("Error: %s errno: %d \n", strerror(errno), errno);
}
printf("count: %zu\n", count );
for(size_t k=0; k<count; k++) {
printf("str: %s\n", res[k]);
}
free(res);
return(0);
}
char ** res; ...; res = (char*) calloc(...).res- указатель на указатель, а приводите вы к указателю наchar. – andy.37 Jun 14 '17 at 07:13res = (char**) calloc(count, sizeof(char*));– andy.37 Jun 14 '17 at 07:18sizeof(char)по определению равно 1. – andy.37 Jun 14 '17 at 07:22sizeof(char)всегда равно 1. Это одно из фундаментальнейших свойств модели памяти и объектной модели С и С++. – AnT stands with Russia Jun 14 '17 at 08:14char,sizeof(char)обязан быть равен 1. Можно считать это "определением 1 в языках С/С++" (касательно sizeof). – andy.37 Jun 14 '17 at 17:15