我正在为一个C课程开发一个程序,我到了一个我不知道该怎么做的地方。我们正在实现一个String库类型。
我有我的头文件(MyString.h)
typedef struct {
char *buffer;
int length;
int maxLength;
} String;
String *newString(const char *str);
实现函数的文件(MyString.c)
#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"
String *newString(const char *str) {
// Allocate memory for the String
String *newStr = (String*)malloc(sizeof(String));
if (newStr == NULL) {
printf("ERROR: Out of memory\n");
return NULL;
}
// Count the number of characters
int count;
for (count = 0; *(str + count) != '\0'; count++);
count++;
// Allocate memory for the buffer
newStr->buffer = (char*)malloc(count * sizeof(char));
if (newStr->buffer == NULL) {
printf("ERROR: Out of memory\n");
return NULL;
}
// Copy into the buffer
while (*str != '\0')
*(newStr->buffer++) = *(str++);
*(++newStr->buffer) = '\0';
// Set the length and maximum length
newStr->length = count;
newStr->maxLength = count;
printf("newStr->buffer: %p\n",newStr->buffer); // For testing purposes
return newStr;
}
测试人员(main.c)
#include <stdio.h>
#include "MyString.h"
main() {
char str[] = "Test character array";
String *testString = newString(str);
printf("testString->buffer: %p\n",testString->buffer); // Testing only
}
问题在于,即使testString指向在newString()中创建的String,它们的缓冲区也指向不同的内存地址。那是为什么?
提前致谢
答案 0 :(得分:2)
使用*(++newStr->buffer)
和*(newStr->buffer++)
,您将newStr->buffer
移动到基本上指向字符串的末尾。您需要修改代码:
#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"
String *newString(const char *str) {
// Allocate memory for the String
String *newStr = (String*)malloc(sizeof(String));
if (newStr == NULL) {
printf("ERROR: Out of memory\n");
return NULL;
}
// Count the number of characters
int count;
for (count = 0; *(str + count) != '\0'; count++);
count++;
// Allocate memory for the buffer
newStr->buffer = (char*)malloc(count * sizeof(char));
if (newStr->buffer == NULL) {
printf("ERROR: Out of memory\n");
return NULL;
}
char *pBuffer = newStr->buffer; // don't move newStr->buffer, have another pointer for that.
// Copy into the buffer
while (*str != '\0')
*(pBuffer++) = *(str++);
*pBuffer = '\0';
// Set the length and maximum length
newStr->length = count;
newStr->maxLength = count;
printf("newStr->buffer: %p\n", newStr->buffer); // For testing purposes
return newStr;
}
答案 1 :(得分:2)
您正在修改新创建的String结构内的缓冲区指针。
你应该这样做:
char *newBuffer = newStr->buffer;
// Copy into the buffer
while (*str != '\0')
*(newBuffer++) = *(str++);
*(++newBuffer) = '\0';
答案 2 :(得分:2)
正如其他同事已经指出的那样,你修改了你的分配指针,这是不行的。在这里你的例子,但翻译成更“专业”的方式。
我会将您的结构更改为:
typedef struct {
char *buffer;
size_t length; /* strings and allocation in C are of type size_t not int */
size_t alloclength;
} String;
String *newString(const char *str);
该功能将更改为。
#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"
String *newString(const char *str)
{
// Allocate memory for the String
String *newStr = malloc(sizeof (String)); /* No typecast of void * in C, it's bad taste. */
if(!newStr) {
fprintf(stderr, "ERROR: Out of memory\n"); /* Errors are meant to be printed on stderr, not stdio */
return NULL;
}
// Count the number of characters
newStr->length = strlen(str); /* Learn to use the stdlib, there are a lot of usefull functions */
newStr->alloclength = newStr->length+1;
// Allocate memory for the buffer
newStr->buffer = malloc(newStr->alloclength); /* sizeof (char) is by definition always 1 */
if(!newStr->buffer) {
fprintf(stderr, "ERROR: Out of memory\n");
return NULL;
}
// Copy into the buffer
strcpy(newStr->buffer, str); /* Because we already scaned the input with strlen, we can use safely the "unsafe" strcpy function. The strcpy will add the trailing 0 */
printf("newStr->buffer: %p\n",newStr->buffer); // For testing purposes
return newStr;
}
答案 3 :(得分:1)
解释非常简单:您正在修改newString()
函数中的缓冲区指针:
// Copy into the buffer
while (*str != '\0')
*(newStr->buffer++) = *(str++);
*(++newStr->buffer) = '\0';
您可以在此处使用临时指针(如其他答案中所述),但我建议您使用string.h
中提供的标准函数:
// Count the number of characters
int count;
count = strlen(str) + 1;
// Copy into the buffer
memcpy(newString->buffer, str, count)
答案 4 :(得分:1)
问题已得到解答,但我认为您应该添加一段代码以避免内存泄漏的微妙来源:
// Allocate memory for the buffer
newStr->buffer = (char*)malloc(count * sizeof(char));
if (newStr->buffer == NULL) {
printf("ERROR: Out of memory\n");
free(newStr); // free the memory allocated for newStr
return NULL;
}