我试图围绕C语言中的堆管理概念。以下代码编译没有警告并且没有错误运行。
Image: /Users/deathstroke/Desktop/lipRead/VidTIMIT/mwbt0/video/sx383/roi081.jpeg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 68x39+0+0
Units: Undefined
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Pixels: 2652
Red:
min: 0 (0)
max: 223 (0.87451)
mean: 139.207 (0.54591)
standard deviation: 44.1822 (0.173263)
kurtosis: 0.798663
skewness: -1.01178
entropy: 0.942718
Green:
min: 0 (0)
max: 159 (0.623529)
mean: 87.1161 (0.341632)
standard deviation: 33.4156 (0.131041)
kurtosis: -0.162594
skewness: -0.485596
entropy: 0.955489
Blue:
min: 0 (0)
max: 249 (0.976471)
mean: 73.9367 (0.289948)
standard deviation: 43.7079 (0.171403)
kurtosis: 2.38585
skewness: 1.43844
entropy: 0.917047
Image statistics:
Overall:
min: 0 (0)
max: 249 (0.976471)
mean: 100.087 (0.392496)
standard deviation: 40.7392 (0.159761)
kurtosis: 2.09684
skewness: 0.445232
entropy: 0.938418
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 68x39+0+0
Dispose: Undefined
Iterations: 0
Compression: JPEG
Quality: 95
Orientation: Undefined
Properties:
date:create: 2016-04-15T23:19:32+06:00
date:modify: 2016-04-15T23:19:32+06:00
jpeg:colorspace: 2
jpeg:sampling-factor: 2x2,1x1,1x1
signature: d3f2c14b57043efd4edbf719dfe769aded504df16c5b9fc8ee436d7551993221
Artifacts:
filename: /Users/deathstroke/Desktop/lipRead/VidTIMIT/mwbt0/video/sx383/roi081.jpeg
verbose: true
Tainted: False
Filesize: 1.81KB
Number pixels: 2.65K
Pixels per second: 265KB
User time: 0.000u
Elapsed time: 0:01.009
Version: ImageMagick 6.9.3-7 Q16 x86_64 2016-03-27 http://www.imagemagick.org
我有几个问题:
我只是想创建一个简单的堆字符串,可以根据需要在程序的不同阶段增加/减少。
感谢。
编辑:
如果我将main中的string_concat()调用更改为以下内容:
char* string_make(char* text) {
size_t len = strlen(text) + 1;
char* str = malloc(len);
memcpy(str, text, len);
return str;
}
char* string_concat(char* x, char* y) {
size_t len_x = strlen(x);
size_t len_y = strlen(y);
x = realloc(x, len_x + len_y + 1);
memcpy(x+len_x, y, len_y+1);
return x;
}
int main (int argc, char const *argv[]) {
char* first = string_make("funny");
char* second = string_make(" duck");
char* third = string_make("! c++");
//
printf("%s\n", string_concat(first, second));
printf("%s\n", string_concat(first, third));
//
free(first);
free(second);
free(third);
}
它会让事情变得合法吗?
答案 0 :(得分:3)
string_make很好。
string_concat不是。它重新分配x,这可能意味着在其他地方分配了更大的内存块,并且原始内存块被标记为空闲。但是,C中的函数不会更改其参数,因此当string_concat返回时,x可能指向标记为free的位置。
答案 1 :(得分:2)
忽略错误检查(在malloc
和realloc
之后),您需要做的只是在main
中替换这两行:
printf("%s\n", string_concat(first, second));
printf("%s\n", string_concat(first, third));
这些行
first = string_concat(first, second);
printf("%s\n", first);
first = string_concat(first, third);
printf("%s\n", first);
原因是参数是按C中的值传递的。因此,更新x
中的string_concat
不会更新first
中的变量main
。所以代码需要使用函数的返回值来更新first
。
现在,您可能会感到困惑,因为您测试了代码并且它似乎有效。那是因为你的最后一个字符串只有16个字节,包括NUL终结符。 malloc
的大多数现代实现都会将大小四舍五入为16的倍数(或者更大的2的幂)。这意味着对string_make
的所有三次调用都返回指向16字节内存区域的指针,即使您请求的更少。这也意味着realloc
可以在不移动缓冲区的情况下扩展缓冲区。正如手册页解释
如果没有足够的空间来扩大内存分配 由ptr指出,realloc()创建一个新的分配,复制尽可能多 ptr指向的旧数据将适合新的分配, 释放旧的分配,并返回指向已分配的指针 存储器中。
在你的情况下, 有足够的空间来扩大内存分配,因此realloc
返回了传入的相同指针。结果,你的代码似乎工作了即使它有严重的缺陷。
答案 2 :(得分:0)
donuts_plot <- function(
panel = runif(3), # counts
pctr = c(.5,.2,.9), # percentage in count
legend.label='',
cols = c('chartreuse', 'chocolate','deepskyblue'), # colors
outradius = 1, # outter radius
radius = .7, # 1-width of the donus
add = F,
innerradius = .5, # innerradius, if innerradius==innerradius then no suggest line
legend = F,
pilabels=F,
legend_offset=.25, # non-negative number, legend right position control
borderlit=c(T,F,T,T)
){
par(new=add)
if(sum(legend.label=='')>=1) legend.label=paste("Series",1:length(pctr))
if(pilabels){
pie(panel, col=cols,border = borderlit[1],labels = legend.label,radius = outradius)
}
panel = panel/sum(panel)
pctr2= panel*(1 - pctr)
pctr3 = c(pctr,pctr)
pctr_indx=2*(1:length(pctr))
pctr3[pctr_indx]=pctr2
pctr3[-pctr_indx]=panel*pctr
cols_fill = c(cols,cols)
cols_fill[pctr_indx]='white'
cols_fill[-pctr_indx]=cols
par(new=TRUE)
pie(pctr3, col=cols_fill,border = borderlit[2],labels = '',radius = outradius)
par(new=TRUE)
pie(panel, col='white',border = borderlit[3],labels = '',radius = radius)
par(new=TRUE)
pie(1, col='white',border = borderlit[4],labels = '',radius = innerradius)
if(legend){
# par(mar=c(5.2, 4.1, 4.1, 8.2), xpd=TRUE)
legend("topright",inset=c(-legend_offset,0),legend=legend.label, pch=rep(15,'.',length(pctr)),
col=cols,bty='n')
}
par(new=FALSE)
}
## col- > subcor(change hue/alpha)
subcolors <- function(.dta,main,mainCol){
tmp_dta = cbind(.dta,1,'col')
tmp1 = unique(.dta[[main]])
for (i in 1:length(tmp1)){
tmp_dta$"col"[.dta[[main]] == tmp1[i]] = mainCol[i]
}
u <- unlist(by(tmp_dta$"1",tmp_dta[[main]],cumsum))
n <- dim(.dta)[1]
subcol=rep(rgb(0,0,0),n);
for(i in 1:n){
t1 = col2rgb(tmp_dta$col[i])/256
subcol[i]=rgb(t1[1],t1[2],t1[3],1/(1+u[i]))
}
return(subcol);
}
### Then get the plot is fairly easy:
# INPUT data
browsers <- structure(list(browser = structure(c(3L, 3L, 3L, 3L, 2L, 2L,
2L, 1L, 5L, 5L, 4L),
.Label = c("Chrome", "Firefox", "MSIE","Opera", "Safari"),class = "factor"),
version = structure(c(5L,6L, 7L, 8L, 2L, 3L, 4L, 1L, 10L, 11L, 9L),
.Label = c("Chrome 10.0", "Firefox 3.5", "Firefox 3.6", "Firefox 4.0", "MSIE 6.0",
"MSIE 7.0","MSIE 8.0", "MSIE 9.0", "Opera 11.x", "Safari 4.0", "Safari 5.0"),
class = "factor"),
share = c(10.85, 7.35, 33.06, 2.81, 1.58,13.12, 5.43, 9.91, 1.42, 4.55, 1.65),
ymax = c(10.85, 18.2, 51.26,54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08, 91.73),
ymin = c(0,10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53,90.08)),
.Names = c("browser", "version", "share", "ymax", "ymin"),
row.names = c(NA, -11L), class = "data.frame")
## data clean
browsers=browsers[order(browsers$browser,browsers$share),]
arr=aggregate(share~browser,browsers,sum)
### choose your cols
mainCol = c('chartreuse3', 'chocolate3','deepskyblue3','gold3','deeppink3')
donuts_plot(browsers$share,rep(1,11),browsers$version,
cols=subcolors(browsers,"browser",mainCol),
legend=F,pilabels = T,borderlit = rep(F,4) )
donuts_plot(arr$share,rep(1,5),arr$browser,
cols=mainCol,pilabels=F,legend=T,legend_offset=-.02,
outradius = .71,radius = .0,innerradius=.0,add=T,
borderlit = rep(F,4) )
###end of line
:如果使用string_concat()
,我会将指针的地址传递给必须为realloc()
- ed的字符串,但返回重新分配的字符串本身。所以我会避免指向可能标记为realloc
的位置的返回值。如果realloc返回NULL,则函数返回指向原始字符串的指针。
free
和
char* string_concat(char** x, char* y) {
size_t len_x = strlen(*x);
size_t len_y = strlen(y);
char *temp = realloc(*x, len_x + len_y + 1);
if(!temp) return *x; //or do some more appropriate error handling
memcpy(temp+len_x, y, len_y+1);
*x = temp;
return *x;
}
很好地解释了here。